Description
\(n\)个国家一共有\(m\)个收集器,每次会在一个范围内落下\(a_i\)个物品,每个国家有收集目标,问每个国家至少多少次可以收集完.\(n,m,k \leqslant 3\times 10^5\)
Solution
整体二分.
二分答案的同时将询问分类,分成小于等于\(mid\),和大于\(mid\),递归操作.
用树状数组差分可以得到单点的权值,因为每层只会进行\(n\)次操作,一共\(logn\)层,所以总复杂度应该是\(O(nlog^2n)\)
Code
/************************************************************** Problem: 2527 User: BeiYu Language: C++ Result: Accepted Time:22716 ms Memory:21396 kb ****************************************************************/ #include <bits/stdc++.h> using namespace std; #define debug(a) cout<<#a<<"="<<a<<" " #define mid ((l+r)>>1) typedef long long LL; typedef pair< int,int > pr; const int N = 3e5+50; const int INF = 1e9+7; inline int in(int x=0,char ch=getchar()) { while(ch>'9' || ch<'0') ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x; } int n,m,k; int a[N],tar[N],t1[N],t2[N],tt[N],ans[N]; vector< int > g[N]; struct Q { int l,r,a; } qr[N]; LL d[N]; void Add(int x,LL v) { for(;x<=m;x+=x&-x) d[x]+=v; } LL Sum(int x,LL r=0) { for(;x;x-=x&-x) r+=d[x];return r; } void Solve(int l,int r,int L,int R) { // debug(l),debug(r),debug(L),debug(R)<<endl; // for(int i=L;i<=R;i++) cout<<a[i]<<" ";cout<<endl; // cout<<"----------------------------------------"<<endl; if(l==r) { for(int i=L;i<=R;i++) ans[a[i]]=l; return; } // if(l==1 && r==k) for(int i=1;i<=m;i++) cout<<Sum(i)<<endl; for(int i=l;i<=mid;i++) { if(qr[i].l<=qr[i].r) Add(qr[i].l,qr[i].a),Add(qr[i].r+1,-qr[i].a); else Add(1,qr[i].a),Add(qr[i].r+1,-qr[i].a),Add(qr[i].l,qr[i].a); } // if(l==1 && r==k) for(int i=1;i<=m;i++) cout<<Sum(i)<<endl; int c1,c2;c1=c2=0; for(int i=L;i<=R;i++) { LL tmp=0; for(int j=0;j<(int)g[a[i]].size();j++) { tmp+=Sum(g[a[i]][j]);if(tmp>=tar[a[i]]) break; } if(tmp>=tar[a[i]]) t1[++c1]=a[i]; else t2[++c2]=a[i]; // cout<<a[i]<<" "<<tmp<<endl; } // debug(c1),debug(c2)<<endl; // cout<<"----------------------------------------"<<endl; for(int i=1;i<=c2;i++) a[L+c1+i-1]=t2[i]; for(int i=1;i<=c1;i++) a[L+i-1]=t1[i]; Solve(mid+1,r,L+c1,R); for(int i=l;i<=mid;i++) { if(qr[i].l<=qr[i].r) Add(qr[i].l,-qr[i].a),Add(qr[i].r+1,qr[i].a); else Add(1,-qr[i].a),Add(qr[i].r+1,qr[i].a),Add(qr[i].l,-qr[i].a); } Solve(l,mid,L,L+c1-1); } int main() { // freopen("in.in","r",stdin); n=in(),m=in(); for(int i=1,x;i<=m;i++) x=in(),g[x].push_back(i); for(int i=1;i<=n;i++) tar[i]=in(),a[i]=i; k=in(); for(int i=1;i<=k;i++) { int ll=in(),rr=in(),aa=in(); qr[i]=(Q){ ll,rr,aa }; } qr[++k]=(Q){ 1,m,INF }; Solve(1,k,1,n); for(int i=1;i<=n;i++) (ans[i]==k)?puts("NIE"):printf("%d\n",ans[i]); return 0; } /* 3 5 1 3 2 1 3 10 5 7 3 4 2 4 1 3 1 3 5 2 */