• 【BZOJ3110】K大数查询(权值线段树套线段树+标记永久化,整体二分)


    题意:有N个位置,M个操作。操作有两种,每次操作

    如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c

    如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。


    N,M<=50000,N,M<=50000

    a<=b<=N

    1操作中abs(c)<=N

    2操作中c<=Maxlongint

    思路:这道题如果外层是位置的话就需要在外层区间更新 并不会写

    所以需要外层权值,内层位置

    然而常数太渣,BZOJ上过不去

    并不想(会)写标记永久化

      1 var t:array[0..20000000]of record
      2                             l,r:longint;
      3                             a,s:int64;
      4                            end;
      5     op,x,y,z,d:array[1..200000]of longint;
      6     root:array[0..1000000]of longint;
      7     n,m,up,i,tmp,n1,cnt:longint;
      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  
     16 function query(l,r,x,y,p:longint):int64;
     17 var mid,k:longint;
     18     tmp:int64;
     19 begin
     20  if p=0 then exit(0);
     21  mid:=(l+r)>>1;
     22  if (t[p].a>0)and(l<r) then
     23  begin
     24   tmp:=t[p].a;
     25   if t[p].l=0 then begin inc(cnt); t[p].l:=cnt; end;
     26   k:=t[p].l;
     27   t[k].a:=t[k].a+tmp;
     28   t[k].s:=t[k].s+tmp*(mid-l+1);
     29   if t[p].r=0 then begin inc(cnt); t[p].r:=cnt; end;
     30   k:=t[p].r;
     31   t[k].a:=t[k].a+tmp;
     32   t[k].s:=t[k].s+tmp*(r-mid);
     33   t[p].a:=0;
     34  end;
     35  if (l>=x)and(r<=y) then exit(t[p].s);
     36  query:=0;
     37  if x<=mid then query:=query+query(l,mid,x,y,t[p].l);
     38  if y>mid then query:=query+query(mid+1,r,x,y,t[p].r);
     39  
     40 end;
     41  
     42 procedure update(l,r,x,y:longint;var p:longint);
     43 var mid,k:longint;
     44     tmp:int64;
     45 begin
     46  if p=0 then begin inc(cnt); p:=cnt; end;
     47  mid:=(l+r)>>1;
     48  if (t[p].a>0)and(l<r) then
     49  begin
     50   tmp:=t[p].a;
     51   if t[p].l=0 then begin inc(cnt); t[p].l:=cnt; end;
     52   k:=t[p].l;
     53   t[k].a:=t[k].a+tmp;
     54   t[k].s:=t[k].s+tmp*(mid-l+1);
     55   if t[p].r=0 then begin inc(cnt); t[p].r:=cnt; end;
     56   k:=t[p].r;
     57   t[k].a:=t[k].a+tmp;
     58   t[k].s:=t[k].s+tmp*(r-mid);
     59   t[p].a:=0;
     60  end;
     61  if (l>=x)and(r<=y) then
     62  begin
     63   t[p].a:=t[p].a+1;
     64   t[p].s:=t[p].s+r-l+1;
     65   exit;
     66  end;
     67  if x<=mid then update(l,mid,x,y,t[p].l);
     68  if y>mid then update(mid+1,r,x,y,t[p].r);
     69  
     70  t[p].s:=t[t[p].l].s+t[t[p].r].s;
     71 end;
     72  
     73 procedure add(a,b,c:longint);
     74 var l,r,k,mid:longint;
     75 begin
     76  l:=1; r:=n+n+1; k:=1;
     77  while l<r do
     78  begin
     79   mid:=(l+r)>>1;
     80   update(1,n,a,b,root[k]);
     81   if c<=mid then
     82   begin
     83    r:=mid; k:=k<<1;
     84   end
     85    else
     86    begin
     87     l:=mid+1; k:=(k<<1)+1;
     88    end;
     89  end;
     90  update(1,n,a,b,root[k]);
     91 end;
     92  
     93 function ask(a,b:longint;c:int64):longint;
     94 var l,r,mid,k:longint;
     95     tmp:int64;
     96 begin
     97  l:=1; r:=n+n+1; k:=1;
     98  while l<r do
     99  begin
    100   mid:=(l+r)>>1;
    101   tmp:=query(1,n,a,b,root[k<<1]);
    102   if tmp>=c then
    103   begin
    104    r:=mid; k:=k<<1;
    105   end
    106    else
    107    begin
    108     l:=mid+1; k:=(k<<1)+1;
    109     c:=c-tmp;
    110    end;
    111  end;
    112  exit(l);
    113 end;
    114  
    115 begin
    116  
    117  readln(n,m);
    118  for i:=1 to m do read(op[i],x[i],y[i],z[i]);
    119  
    120  for i:=1 to m do
    121   if op[i]=1 then add(x[i],y[i],n+1-z[i])
    122  
    123    else writeln(n+1-ask(x[i],y[i],z[i]));
    124  
    125  
    126  
    127 end.

    2017.3.19

    想了想还是学一波奇技淫巧

    需要注意的是标记永久化只能用(l=x)and(r=y)的写法写

      1 var t:array[0..20000000]of record
      2                             l,r:longint;
      3                             a,s:int64;
      4                            end;
      5     op,x,y,z,d:array[1..200000]of longint;
      6     root:array[0..1000000]of longint;
      7     n,m,up,i,tmp,n1,cnt:longint;
      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(l,r,p:longint);
     16 begin
     17  t[p].s:=t[t[p].l].s+t[t[p].r].s+t[p].a*(r-l+1);
     18 end;
     19   
     20 function query(l,r,x,y,p:longint):int64;
     21 var mid:longint;
     22     ans:int64;
     23 begin
     24  if p=0 then exit(0);
     25  if (l=x)and(r=y) then exit(t[p].s);
     26  mid:=(l+r)>>1;
     27  query:=0;
     28  ans:=t[p].a*(y-x+1);
     29        if y<=mid then exit(query(l,mid,x,y,t[p].l)+ans)
     30   else if x>mid then exit(query(mid+1,r,x,y,t[p].r)+ans)
     31   else exit(query(l,mid,x,mid,t[p].l)+query(mid+1,r,mid+1,y,t[p].r)+ans);
     32 end;
     33   
     34 procedure update(l,r,x,y:longint;var p:longint);
     35 var mid,k:longint;
     36     tmp:int64;
     37 begin
     38  if p=0 then begin inc(cnt); p:=cnt; end;
     39  mid:=(l+r)>>1;
     40  if (l=x)and(r=y) then
     41  begin
     42   t[p].a:=t[p].a+1;
     43   t[p].s:=t[p].s+r-l+1;
     44   exit;
     45  end;
     46       if y<=mid then update(l,mid,x,y,t[p].l)
     47  else if x>mid then update(mid+1,r,x,y,t[p].r)
     48  else
     49  begin
     50   update(l,mid,x,mid,t[p].l);
     51   update(mid+1,r,mid+1,y,t[p].r);
     52  end;
     53  pushup(l,r,p);
     54 end;
     55   
     56 procedure add(a,b,c:longint);
     57 var l,r,k,mid:longint;
     58 begin
     59  l:=1; r:=n+n+1; k:=1;
     60  while l<r do
     61  begin
     62   mid:=(l+r)>>1;
     63   update(1,n,a,b,root[k]);
     64   if c<=mid then
     65   begin
     66    r:=mid; k:=k<<1;
     67   end
     68    else
     69    begin
     70     l:=mid+1; k:=(k<<1)+1;
     71    end;
     72  end;
     73  update(1,n,a,b,root[k]);
     74 end;
     75   
     76 function ask(a,b:longint;c:int64):longint;
     77 var l,r,mid,k:longint;
     78     tmp:int64;
     79 begin
     80  l:=1; r:=n+n+1; k:=1;
     81  while l<r do
     82  begin
     83   mid:=(l+r)>>1;
     84   tmp:=query(1,n,a,b,root[k<<1]);
     85   if tmp>=c then
     86   begin
     87    r:=mid; k:=k<<1;
     88   end
     89    else
     90    begin
     91     l:=mid+1; k:=(k<<1)+1;
     92     c:=c-tmp;
     93    end;
     94  end;
     95  exit(l);
     96 end;
     97    
     98 begin
     99    
    100  readln(n,m);
    101  for i:=1 to m do read(op[i],x[i],y[i],z[i]);
    102    
    103  for i:=1 to m do
    104   if op[i]=1 then add(x[i],y[i],n+1-z[i])
    105    
    106    else writeln(n+1-ask(x[i],y[i],z[i]));
    107   
    108   
    109   
    110 end.

     整体二分是二分答案,CDQ分治是二分操作序列

    比树套树快2倍

      1 var a,b:array[1..100000]of record
      2                           l,r,id,op:longint;
      3                           w:int64;
      4                          end;
      5     s1,s2:array[1..100000]of int64;
      6     flag,ans:array[1..100000]of longint;
      7     n,m,i,cnt:longint;
      8 
      9 function lowbit(x:longint):longint;
     10 begin
     11  exit(x and (-x));
     12 end;
     13 
     14 procedure add(x,y:longint);
     15 var i:longint;
     16 begin
     17  i:=x;
     18  while i<=n do
     19  begin
     20   s1[i]:=s1[i]+y;
     21   s2[i]:=s2[i]+y*x;
     22   i:=i+lowbit(i);
     23  end;
     24 end;
     25 
     26 procedure update(a,b,c:longint);
     27 begin
     28  add(a,c); add(b+1,-c);
     29 end;
     30 
     31 function query(x:longint):int64;
     32 var i:longint;
     33 begin
     34  i:=x; query:=0;
     35  while i>0 do
     36  begin
     37   query:=query+s1[i]*(x+1)-s2[i];
     38   i:=i-lowbit(i);
     39  end;
     40 end;
     41 
     42 function ask(a,b:longint):int64;
     43 begin
     44  exit(query(b)-query(a-1));
     45 end;
     46 
     47 procedure solve(x,y,l,r:longint);
     48 var i,mid,pre,now:longint;
     49     tmp:int64;
     50 begin
     51  if l=r then
     52  begin
     53   for i:=x to y do
     54    if a[i].op=2 then ans[a[i].id]:=l;
     55   exit;
     56  end;
     57  mid:=(l+r)>>1;
     58  pre:=x; now:=x;
     59  for i:=x to y do
     60   if a[i].op=1 then
     61   begin
     62    if a[i].w<=mid then
     63    begin
     64     update(a[i].l,a[i].r,1);
     65     flag[i]:=0;
     66     inc(now);
     67    end
     68     else flag[i]:=1;
     69   end
     70    else
     71    begin
     72     tmp:=ask(a[i].l,a[i].r);
     73     if tmp>=a[i].w then
     74     begin
     75      inc(now); flag[i]:=0;
     76     end
     77      else
     78      begin
     79       flag[i]:=1;
     80       a[i].w:=a[i].w-tmp;
     81      end;
     82    end;
     83  for i:=x to y do
     84   if (a[i].op=1)and(a[i].w<=mid) then update(a[i].l,a[i].r,-1);
     85  for i:=x to y do
     86   if flag[i]=1 then
     87   begin
     88    b[now]:=a[i]; inc(now);
     89   end
     90    else
     91    begin
     92     b[pre]:=a[i]; inc(pre);
     93    end;
     94  for i:=x to y do a[i]:=b[i];
     95  solve(x,pre-1,l,mid);
     96  solve(pre,y,mid+1,r);
     97 end;
     98 
     99 begin
    100  assign(input,'bzoj3110.in'); reset(input);
    101  assign(output,'bzoj3110.out'); rewrite(output);
    102  read(n,m);
    103  for i:=1 to m do
    104  begin
    105   read(a[i].op,a[i].l,a[i].r,a[i].w);
    106   if a[i].op=1 then a[i].w:=n-a[i].w+1
    107    else
    108    begin
    109     inc(cnt); a[i].id:=cnt;
    110    end;
    111  end;
    112  solve(1,m,1,2*n+1);
    113  for i:=1 to cnt do writeln(n-ans[i]+1);
    114  close(input);
    115  close(output);
    116 end.
  • 相关阅读:
    L3-015. 球队“食物链”【DFS + 剪枝】
    L3-002. 堆栈【主席树 or 线段树 or 分块】
    PTA L1-006 连续因子【暴力模拟】
    【路由和交换之H3C自导自演】
    【ospf-stub区域配置】
    【ospf-链路验证】
    【ospf-vlink虚拟连接】
    【c学习-14】
    【c学习-13】
    【php学习-5】
  • 原文地址:https://www.cnblogs.com/myx12345/p/6566832.html
Copyright © 2020-2023  润新知