C139 线段树分治+01背包 CF601E A Museum Robbery
视频链接:C139 线段树分治+01背包 CF601E A Museum Robbery_哔哩哔哩_bilibili
E08【模板】背包DP 01背包 - 董晓 - 博客园 (cnblogs.com)
CF601E A Museum Robbery - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
// 线段树分治 O((n+q)*k*logq + qk) #include <iostream> #include <cstring> #include <algorithm> #include <vector> using namespace std; #define ll long long #define ls (u<<1) #define rs (u<<1|1) #define mid ((l+r)>>1) const int N=100005; const ll P=1e7+19; const ll Q=1e9+7; int n,k,q; ll f[N]; struct item{ //物品 int l,r,v,w; }e[N]; vector<item>tr[N<<2]; //节点 void insert(int u,int l,int r,int L,int R,int i){ if(L>r||R<l) return; if(l>=L && r<=R)return tr[u].push_back(e[i]); insert(ls,l,mid,L,R,i); insert(rs,mid+1,r,L,R,i); } void solve(int u,int l,int r,ll *f){ ll s[N]; for(int i=1;i<=k;++i) s[i]=f[i]; for(auto i:tr[u]) for(int j=k;j>=i.w;--j) s[j]=max(s[j],s[j-i.w]+i.v); if(l==r){ ll b=1,ans=0; for(int i=1;i<=k;i++){ ans=(ans+s[i]*b)%Q; b=b*P%Q; } printf("%lld\n",ans); } else solve(ls,l,mid,s),solve(rs,mid+1,r,s); } int main(){ cin>>n>>k; int v,w,tot=0; for(int i=1;i<=n;++i){ cin>>v>>w; //v价值 w质量 e[++tot]={1,-1,v,w}; } cin>>q; int cnt=0; for(int i=1,opt,x;i<=q;++i){ cin>>opt; if(opt==1){ //添加 cin>>v>>w; e[++tot]={cnt+1,-1,v,w}; } if(opt==2){ //删除 cin>>x; e[x].r=cnt; //x的结束时刻 } if(opt==3)++cnt; //询问时刻 } for(int i=1;i<=tot;++i){ if(e[i].r==-1) e[i].r=cnt; insert(1,1,cnt,e[i].l,e[i].r,i); } solve(1,1,cnt,f); }