【BZOJ2527】Meteors(整体二分)
题意:
Byteotian Interstellar Union有N个成员国。现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站。
这个星球经常会下陨石雨。BIU已经预测了接下来K场陨石雨的情况。
BIU的第i个成员国希望能够收集Pi单位的陨石样本。你的任务是判断对于每个国家,它需要在第几次陨石雨之后,才能收集足够的陨石。
输入:
第一行是两个数N,M。
第二行有M个数,第i个数Oi表示第i段轨道上有第Oi个国家的太空站。
第三行有N个数,第i个数Pi表示第i个国家希望收集的陨石数量。
第四行有一个数K,表示BIU预测了接下来的K场陨石雨。
接下来K行,每行有三个数Li,Ri,Ai,表示第K场陨石雨的发生地点在从Li顺时针到Ri的区间中(如果Li<=Ri,就是Li,Li+1,...,Ri,否则就是Ri,Ri+1,...,m-1,m,1,...,Li),向区间中的每个太空站提供Ai单位的陨石样本。
输出:
N行。第i行的数Wi表示第i个国家在第Wi波陨石雨之后能够收集到足够的陨石样本。如果到第K波结束后仍然收集不到,输出NIE。
数据范围: 1<=n,m,k<=3*10^5 1<=Pi<=10^9 1<=Ai<10^9
思路:RYZ作业
整体二分很显然,卡了5-6天,线段树标记持久化都过不去,树状数组暴力清空也T,实在是没办法了……
1 var s1,s2:array[1..400000]of extended; 2 t:array[1..400000]of longint; 3 c,q:array[1..710000]of record 4 l,r,op,t:longint; 5 a:int64; 6 s:extended; 7 end; 8 b:array[1..710000]of extended; 9 head,vet,next,ans,flag:array[1..710000]of longint; 10 n,m,i,k,tot,x,time:longint; 11 12 procedure add(x:longint;y:extended); 13 var i:longint; 14 begin 15 i:=x; 16 while i<=m do 17 begin 18 if t[i]<>time then 19 begin 20 s1[i]:=0; s2[i]:=0; t[i]:=time; 21 end; 22 s1[i]:=s1[i]+y; 23 s2[i]:=s2[i]+y*x; 24 i:=i+i and (-i); 25 end; 26 end; 27 28 function query(x:longint):extended; 29 var i:longint; 30 begin 31 query:=0; i:=x; 32 while i>0 do 33 begin 34 if t[i]=time then query:=query+s1[i]*(x+1)-s2[i]; 35 i:=i-i and (-i); 36 end; 37 end; 38 39 procedure solve(x,y,l,r:longint); 40 var i,j,mid,pre,now,u,e,v:longint; 41 tmp:extended; 42 begin 43 if l>r then exit; 44 if l=r then 45 begin 46 for i:=x to y do 47 if c[i].op=2 then ans[c[i].a]:=l; 48 exit; 49 end; 50 mid:=(l+r)>>1; 51 pre:=x; now:=x; inc(time); 52 for i:=x to y do 53 if c[i].op=1 then 54 begin 55 if c[i].t<=mid then 56 begin 57 if c[i].l>c[i].r then 58 begin 59 add(c[i].l,c[i].a); 60 add(1,c[i].a); 61 add(c[i].r+1,-c[i].a); 62 end 63 else 64 begin 65 add(c[i].l,c[i].a); 66 add(c[i].r+1,-c[i].a); 67 end; 68 flag[i]:=0; 69 inc(now); 70 end 71 else flag[i]:=1; 72 end; 73 for i:=x to y do 74 if c[i].op=2 then 75 begin 76 u:=c[i].a; tmp:=0; 77 e:=head[u]; 78 while e<>0 do 79 begin 80 v:=vet[e]; 81 tmp:=tmp+query(v)-query(v-1); 82 if tmp>=c[i].s then break; 83 e:=next[e]; 84 end; 85 if tmp>=c[i].s then 86 begin 87 inc(now); flag[i]:=0; 88 end 89 else 90 begin 91 flag[i]:=1; c[i].s:=c[i].s-tmp; 92 end; 93 end; 94 95 for i:=x to y do 96 if flag[i]=1 then 97 begin 98 q[now]:=c[i]; inc(now); 99 end 100 else 101 begin 102 q[pre]:=c[i]; inc(pre); 103 end; 104 for i:=x to y do c[i]:=q[i]; 105 solve(x,pre-1,l,mid); 106 solve(pre,y,mid+1,r); 107 end; 108 109 procedure add(a,b:longint); 110 begin 111 inc(tot); 112 next[tot]:=head[a]; 113 vet[tot]:=b; 114 head[a]:=tot; 115 end; 116 117 begin 118 119 read(n,m); 120 for i:=1 to m do 121 begin 122 read(x); 123 add(x,i); 124 end; 125 for i:=1 to n do read(b[i]); 126 read(k); 127 for i:=1 to k do 128 begin 129 read(c[i].l,c[i].r,c[i].a); 130 c[i].op:=1; c[i].t:=i; 131 end; 132 for i:=1 to n do 133 begin 134 c[i+k].op:=2; 135 c[i+k].a:=i; c[i+k].s:=b[i]; 136 end; 137 138 solve(1,k+n,1,k+1); 139 for i:=1 to n do 140 if ans[i]<=k then writeln(ans[i]) 141 else writeln('NIE'); 142 143 end.
null