zoukankan      html  css  js  c++  java
  • 【Hihocoder1034】毁灭者问题(splay,树状数组)

    题意:

    假设你拥有 n 个魔法单位,他们从左到有站在一行,编号从 1 到 n。 每个单位拥有三项属性:

     

    • si: 初始法力。

    • mi: 最大法力上限。

    • ri: 每秒中法力回复速度。

     

    现在你操纵一个毁灭者,有 m 个操作,t l r,表示时刻 t,毁灭者对所有编号从 l 到 r 的单位,使用了魔法吸收。操作按照时间顺序给出,计算毁灭者一共吸收了多少法力。

    n<=10^5 s[i],m[i],r[i]<=10^5 m<=10^5 maxtime<=10^9

    思路:RYZ作业

    因为每个人的回复速度不同且都有上限,所以不能用线段树完成

    转换思路,不能维护每个人的魔法值,就应该维护时间点与时间间隔

    考虑单位i,假设它回满的时间长为man,那么它对答案的贡献就是s1*r[i]+s2*m[i]

    其中s1为<man的间隔的总和,s2为>=man的间隔的个数

    现在问题转化成:

    时间间隔需要维护插入,删除,子树大小和子树和,平衡树即可

    时间点需要维护前驱,后继,插入,删除,我用树状数组,每次操作O(log^2 n),如果用平衡树可以达到O(log n)

    需要注意的是查询[0,man-1]这段区间时需要找到第一个>man-1的位置,而查询[man,oo]这段时需要找到最后一个<man的位置,所以rank函数不能共用

    总复杂度O(m log^2 n),维护时间时使用平衡树可以达到O(m log n)

    不过m,n只有100000,煮不在糊

    话说这个OJ不能用P交,那只能用对拍了

      1 var t:array[0..300000,0..1]of longint;
      2     size,fa,l1,l2,l3,r1,r2,r3,
      3     x,y,z,c,time,t1,t2,t3,s,m,r,q:array[0..300000]of longint;
      4     sum,num:array[0..300000]of int64;
      5     n,i,que,head,tail,up,k,tot,root,cnt,k1,k2,man,kk,tmp,j:longint;
      6     ans1,ans2,s1,s2:int64;
      7     flag:boolean;
      8 
      9 procedure swap(var x,y:longint);
     10 var t:longint;
     11 begin
     12  t:=x; x:=y; y:=t;
     13 end;
     14 
     15 procedure pushup(x:longint);
     16 var l,r:longint;
     17 begin
     18  l:=t[x,0]; r:=t[x,1];
     19  size[x]:=size[l]+size[r]+1;
     20 // size[x]:=size[l]+size[r];
     21  sum[x]:=sum[l]+sum[r];
     22  if (num[x]<>maxlongint)and(num[x]<>-1) then sum[x]:=sum[x]+num[x];
     23 end;
     24 
     25 procedure rotate(x:longint;var k:longint);
     26 var y,z,l,r:longint;
     27 begin
     28  y:=fa[x]; z:=fa[y];
     29  if t[y,0]=x then l:=0
     30   else l:=1;
     31  r:=l xor 1;
     32  if y<>k then
     33  begin
     34   if t[z,0]=y then t[z,0]:=x
     35    else t[z,1]:=x;
     36  end
     37   else k:=x;
     38  fa[x]:=z; fa[y]:=x; fa[t[x,r]]:=y;
     39  t[y,l]:=t[x,r]; t[x,r]:=y;
     40  pushup(y);
     41  pushup(x);
     42 end;
     43 
     44 procedure splay(x:longint;var k:longint);
     45 var y,z:longint;
     46 begin
     47  while x<>k do
     48  begin
     49   y:=fa[x]; z:=fa[y];
     50   if y<>k then
     51   begin
     52    if (t[y,0]=x)xor(t[z,0]=y) then rotate(x,k)
     53     else rotate(y,k);
     54   end
     55    else k:=x;
     56   rotate(x,k);
     57  end;
     58 end;
     59 
     60 function kth(x:longint):longint;
     61 var k,tmp:longint;
     62 begin
     63  k:=root;
     64  while true do
     65  begin
     66   tmp:=size[t[k,0]]+1;
     67   if tmp=x then exit(k);
     68   if tmp>x then k:=t[k,0]
     69    else
     70    begin
     71     k:=t[k,1]; x:=x-tmp;
     72    end;
     73  end;
     74 end;
     75 
     76 function pred(x:longint):longint;
     77 var k,last:longint;
     78 begin
     79  k:=root; last:=num[root];
     80  while k<>0 do
     81  begin
     82   if num[k]<x then begin last:=num[k]; k:=t[k,1]; end
     83    else k:=t[k,0];
     84  end;
     85  exit(last);
     86 end;
     87 
     88 function succ(x:longint):longint;
     89 var k,last:longint;
     90 begin
     91  k:=root; last:=maxlongint;
     92  while k<>0 do
     93  begin
     94   if num[k]>x then begin last:=num[k]; k:=t[k,0]; end
     95    else k:=t[k,1];
     96  end;
     97  exit(last);
     98 end;
     99 
    100 function rank(x:longint):longint;
    101 var k:longint;
    102 begin
    103  if x=-1 then exit(1);
    104  x:=pred(x);
    105  k:=root; rank:=0;
    106  while k>0 do
    107  begin
    108   if num[k]<=x then begin rank:=rank+size[t[k,0]]+1; k:=t[k,1]; end
    109    else k:=t[k,0];
    110  end;
    111  inc(rank);
    112 end;
    113 
    114 procedure ins(x:longint);
    115 var k,l,r:longint;
    116 begin
    117  if x=0 then exit;
    118 // if x<0 then begin writeln('error ',i);  exit; end;
    119  k:=rank(x);
    120  l:=kth(k-1);
    121  r:=kth(k);
    122  splay(l,root);
    123  splay(r,t[root,1]);
    124  k:=t[root,1];
    125  inc(cnt); t[k,0]:=cnt; fa[cnt]:=k;
    126  size[cnt]:=1;  num[cnt]:=x; sum[cnt]:=x;
    127  inc(tot);
    128 // writeln('ins ',x,' ',tot);
    129 end;
    130 
    131 procedure del(x:longint);
    132 var k,l,r,k1,k2:longint;
    133 begin
    134  if x=0 then exit;
    135  k:=rank(x);
    136  l:=kth(k-1);
    137  r:=kth(k+1);
    138  splay(l,root);
    139  splay(r,t[root,1]);
    140  k1:=t[root,1]; k2:=t[k1,0];
    141  size[k1]:=size[t[k1,1]]+1;
    142  //sum[k1]:=sum[t[k1,1]]+num[k1];
    143  sum[k1]:=sum[t[k1,1]];
    144  if (num[k1]<>maxlongint)and(num[k1]<>-1) then sum[k1]:=sum[k1]+num[k1];
    145  fa[k2]:=0; sum[k2]:=0;  size[k2]:=0;
    146  t[k2,0]:=0; t[k2,1]:=0; num[k2]:=0;
    147  t[k1,0]:=0;
    148  dec(tot);
    149  //writeln('del ',x,' ',tot);
    150 end;
    151 
    152 function lowbit(x:longint):longint;
    153 begin
    154  exit(x and (-x));
    155 end;
    156 
    157 function sumbit(x:longint):longint;
    158 begin
    159  sumbit:=0;
    160  while x>0 do
    161  begin
    162   sumbit:=sumbit+q[x];
    163   x:=x-lowbit(x);
    164  end;
    165 end;
    166 
    167 procedure add(x,s:longint);
    168 begin
    169  while x<=200000 do
    170  begin
    171   q[x]:=q[x]+s;
    172   x:=x+lowbit(x);
    173  end;
    174 end;
    175 
    176 procedure qsort1(l,r:longint);
    177 var mid,i,j:longint;
    178 begin
    179  i:=l; j:=r; mid:=l1[(l+r)>>1];
    180  repeat
    181   while mid>l1[i] do inc(i);
    182   while mid<l1[j] do dec(j);
    183   if i<=j then
    184   begin
    185    swap(l1[i],l1[j]);
    186    swap(r1[i],r1[j]);
    187    swap(t1[i],t1[j]);
    188    inc(i); dec(j);
    189   end;
    190  until i>j;
    191  if l<j then qsort1(l,j);
    192  if i<r then qsort1(i,r);
    193 end;
    194 
    195 procedure qsort2(l,r:longint);
    196 var mid,i,j:longint;
    197 begin
    198  i:=l; j:=r; mid:=r2[(l+r)>>1];
    199  repeat
    200   while mid>r2[i] do inc(i);
    201   while mid<r2[j] do dec(j);
    202   if i<=j then
    203   begin
    204    swap(l2[i],l2[j]);
    205    swap(r2[i],r2[j]);
    206    swap(t2[i],t2[j]);
    207    inc(i); dec(j);
    208   end;
    209  until i>j;
    210  if l<j then qsort2(l,j);
    211  if i<r then qsort2(i,r);
    212 end;
    213 
    214 function findkth(x:longint):longint;
    215 var l,r,mid,last,tmp:longint;
    216 begin
    217  l:=1; r:=200000; last:=0;
    218  while l<=r do
    219  begin
    220   mid:=(l+r)>>1;
    221   tmp:=sumbit(mid);
    222   {if tmp<=x then begin last:=mid; l:=mid+1; end
    223    //else r:=mid-1;     }
    224   if tmp>x then r:=mid-1
    225    else if tmp<x then begin last:=mid;  l:=mid+1 end
    226     else if tmp=x then begin last:=mid; r:=mid-1; end;
    227 
    228  end;
    229  if sumbit(last)<x then inc(last);
    230  exit(last);
    231 end;
    232 
    233 {function findkth(x:longint):longint;
    234 var ret,p:longint;
    235 begin
    236  p:=1<<17; ret:=0;
    237  while p>0 do
    238  begin
    239   if q[ret+p]<=x then
    240   begin
    241    ret:=ret+p;
    242    x:=x-q[ret];
    243   end;
    244   p:=p>>1;
    245  end;
    246  exit(ret);
    247 end;  }
    248 
    249 function hash(x:longint):longint;
    250 var l,r,mid,last:longint;
    251 begin
    252  l:=1; r:=up; last:=0;
    253  while l<=r do
    254  begin
    255   mid:=(l+r)>>1;
    256   if time[mid]=x then exit(mid)
    257    else if time[mid]>x then r:=mid-1
    258     else l:=mid+1;
    259  end;
    260  //exit(last);
    261 end;
    262 
    263 function querymn(x:longint):int64;
    264 var k1,k2:longint;
    265 begin
    266  k1:=kth(1);
    267  k2:=kth(rank(succ(x-1)));
    268  splay(k1,root);
    269  splay(k2,t[root,1]);
    270  exit(sum[t[k2,0]]);
    271 // exit(size[t[k2,0]]);
    272 end;
    273 
    274 function querymx(x:longint):int64;
    275 var k1,k2,s:longint;
    276 begin
    277  k1:=pred(x);
    278  k:=root; s:=0;
    279  while k>0 do
    280  begin
    281   if num[k]<=k1 then begin s:=s+size[t[k,0]]+1; k:=t[k,1]; end
    282    else k:=t[k,0];
    283  end;
    284 
    285  k1:=kth(s);
    286  k2:=kth(tot);
    287  splay(k1,root);
    288  splay(k2,t[root,1]);
    289  exit(size[t[k2,0]]);
    290 end;
    291 
    292 function min(x,y:longint):longint;
    293 begin
    294  if x<y then exit(x);
    295  exit(y);
    296 end;
    297 
    298 function max(x,y:longint):longint;
    299 begin
    300  if x>y then exit(x);
    301  exit(y);
    302 end;
    303 
    304 begin
    305  assign(input,'data.in'); reset(input);
    306  assign(output,'hihocoder1034.out'); rewrite(output);
    307  readln(n);
    308  for i:=1 to n do read(s[i],m[i],r[i]);
    309  readln(que);
    310  for i:=1 to que do
    311  begin
    312   read(x[i],y[i],z[i]);
    313   inc(x[i]);
    314  end;
    315  l1:=y; r1:=z; t1:=x;
    316  l2:=y; r2:=z; t2:=x;
    317  l3:=y; r3:=z; t3:=x;
    318  qsort1(1,que);
    319  qsort2(1,que);
    320 
    321  if time[1]=1 then begin time[1]:=1; up:=1; end
    322   else begin time[1]:=1; time[2]:=t3[1]; up:=2; end;
    323  for i:=2 to que do
    324   if t3[i]<>time[up] then begin inc(up); time[up]:=t3[i]; end;
    325  inc(up); time[up]:=maxlongint;
    326  add(1,1);
    327  add(200000,1);
    328  num[1]:=maxlongint; size[1]:=2;
    329  t[1,0]:=2;
    330  num[2]:=-1; fa[2]:=1; size[2]:=1;
    331  root:=1; cnt:=2; tot:=2;
    332  //for i:=1 to que do c[i]:=hash(x[i]);
    333  head:=1; tail:=1;
    334 
    335  for i:=1 to n do
    336  begin
    337 
    338 
    339   if r[i]=0 then man:=maxlongint-1
    340    else
    341    begin
    342     if m[i] mod r[i]=0 then man:=m[i] div r[i]
    343      else man:=m[i] div r[i]+1;
    344    end;
    345 
    346   while (head<=que)and(i>=l1[head]) do
    347   begin
    348    kk:=hash(t1[head]);
    349    k:=sumbit(kk-1)+1;
    350    k1:=findkth(k-1);
    351    k2:=findkth(k);
    352    ins(t1[head]-time[k1]);
    353    if k2<>200000 then ins(time[k2]-t1[head]);
    354    if k2<>200000 then del(time[k2]-time[k1]);
    355    add(kk,1); inc(head);
    356   end;
    357 
    358   while (tail<=que)and(i>r2[tail]) do
    359   begin
    360    kk:=hash(t2[tail]);
    361    k:=sumbit(kk-1)+1;
    362    k1:=findkth(k-1);
    363    k2:=findkth(k+1);
    364    if k2<>200000 then ins(time[k2]-time[k1]);
    365    del(t2[tail]-time[k1]);
    366    if k2<>200000 then del(time[k2]-t2[tail]);
    367    add(kk,-1); inc(tail);
    368   end;
    369 
    370 
    371   s1:=querymn(man);
    372   s2:=querymx(man);
    373   ans1:=ans1+s1*r[i]+s2*m[i];
    374 
    375  { s1:=0;
    376   for j:=1 to cnt do
    377    if (num[j]<>0)and(num[j]<man) then inc(s1);
    378   s2:=0;
    379   for j:=1 to cnt do
    380    if (num[j]<>0)and(num[j]>=man) then inc(s2);
    381 
    382   ans2:=ans2+s1*r[i]+s2*m[i];                   }
    383   k:=findkth(2);
    384   if k<>200000 then
    385   begin
    386    tmp:=time[k];
    387    s1:=tmp-1;
    388    s1:=s1*r[i];
    389    if m[i]<s1 then s1:=m[i]; //start with 0
    390    s2:=tmp-1;
    391    s2:=s2*r[i]+s[i];
    392    if m[i]<s2 then s2:=m[i]; //start with s[i]
    393    ans1:=ans1-s1+s2;
    394   end;
    395  // writeln(ans1);
    396   //writeln(ans2);
    397 
    398  end;
    399 
    400  writeln(ans1);
    401 
    402  close(input);
    403  close(output);
    404 end.
  • 相关阅读:
    AC自动机模板
    KMP 模板
    HDU 2746 Cyclic Nacklace
    LCS模板
    POJ 1159 Palindrome
    LIS n^2&nlogn模板
    Codeforces Round #Pi (Div. 2) C. Geometric Progression
    Codeforces Beta Round #25 (Div. 2 Only)E. Test
    Codeforces Beta Round #25 (Div. 2 Only)D. Roads not only in Berland
    bzoj5055 膜法师
  • 原文地址:https://www.cnblogs.com/myx12345/p/6391378.html
Copyright © 2011-2022 走看看