整体二分……感谢zyf提供的入门题
简单粗暴的做法:枚举每一个国家,二分他的$w_i$,然后计算……然而这样效率很低……
整体二分就是:对所有的国家一起进行二分,$w_i$在mid之前的,进左边,否则进右边(是不是很像线段树呀~其实就是吧……
其实感觉代码写起来也跟线段树有些相似?
RE:我没有在结束的时候加if (L==R) return;这样的话,只靠开头的 if (!V[o].size()) return;当极限数据的时候,走到叶子再乘二的话,就超出4*N的范围了……就跑到外面去了……所以就RE了……
1 /************************************************************** 2 Problem: 2527 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:17700 ms 7 Memory:56832 kb 8 ****************************************************************/ 9 10 //BZOJ 2527 11 #include<cstdio> 12 #include<vector> 13 #include<cstring> 14 #include<cstdlib> 15 #include<iostream> 16 #include<algorithm> 17 #define rep(i,n) for(int i=0;i<n;++i) 18 #define F(i,j,n) for(int i=j;i<=n;++i) 19 #define D(i,j,n) for(int i=j;i>=n;--i) 20 #define pb push_back 21 using namespace std; 22 typedef long long LL; 23 inline int getint(){ 24 int r=1,v=0; char ch=getchar(); 25 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 26 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 27 return r*v; 28 } 29 const int N=3e5+10; 30 /*******************template********************/ 31 32 33 int n,m,K,p[N],l[N],r[N],a[N],ans[N],tot; 34 vector<int>G[N],V[N<<2]; 35 LL c[N]; 36 void add(int x,LL v){ 37 for(;x<=m;x+=x&(-x)) c[x]+=v; 38 } 39 LL sum(int x){ 40 LL r=0; 41 for(;x;x-=x&(-x)) r+=c[x]; 42 return r; 43 } 44 void solve(int o,int L,int R){ 45 if (!V[o].size()) return; 46 int mid=(L+R)>>1; 47 F(i,L,mid){ 48 if (l[i]>r[i]) add(1,a[i]); 49 add(l[i],a[i]); add(r[i]+1,-a[i]); 50 } 51 rep(i,V[o].size()){ 52 int x=V[o][i]; LL y=0; 53 rep(j,G[x].size()){ 54 y+=sum(G[x][j]); 55 if (y>=p[x]) break; 56 } 57 if (y>=p[x]){ 58 if (L==R) ans[x]=L; 59 else V[o<<1].pb(x); 60 }else{ 61 if (L==R) ans[x]=-1; 62 else{ 63 p[x]-=y; 64 V[o<<1|1].pb(x); 65 } 66 } 67 } 68 F(i,L,mid){ 69 if (l[i]>r[i]) add(1,-a[i]); 70 add(l[i],-a[i]); add(r[i]+1,a[i]); 71 } 72 if (L==R) return; 73 solve(o<<1,L,mid); solve(o<<1|1,mid+1,R); 74 } 75 76 int main(){ 77 #ifndef ONLINE_JUDGE 78 freopen("2527.in","r",stdin); 79 freopen("2527.out","w",stdout); 80 #endif 81 n=getint(); m=getint(); 82 F(i,1,m){ 83 int x=getint(); 84 G[x].pb(i); 85 } 86 F(i,1,n) p[i]=getint(); 87 K=getint(); 88 F(i,1,K){ 89 l[i]=getint(); r[i]=getint(); a[i]=getint(); 90 } 91 F(i,1,n) V[1].pb(i); 92 solve(1,1,K); 93 F(i,1,n){ 94 if (ans[i]!=-1) printf("%d\n",ans[i]); 95 else puts("NIE"); 96 } 97 return 0; 98 } 99