【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.

 

 

posted on 2017-03-20 10:57  myx12345  阅读(180)  评论(0编辑  收藏  举报

导航