zoukankan      html  css  js  c++  java
  • bzoj1901

    带修改的主席树
    怎么搞呢,由于主席树满足减法性质,且维护的是前缀信息,所以我们不难想到套一个树状数组来优化
    也很好理解,对于第i个位置,修改对后面的lowbit+都修改,求和lowbit-都求和
    由于修改要修改logn个树,每棵树都要开辟logS个节点,所以空间复杂度是两个log值得注意
    有修改还要将修改成的数一并离散化,所以带修改的主席树是一个离线数据结构

      1 type node=record
      2        wh:char;
      3        l,r,x:longint;
      4      end;
      5      point=record
      6        l,r,s:longint;
      7      end;
      8 
      9 var q:array[0..10010] of node;
     10     tree:array[0..3000010] of point;
     11     h,c,a,w,sa,d1,d2:array[0..20010] of longint;
     12     j,s,p,last,t,t1,t2,x,i,n,m:longint;
     13 
     14 function lowbit(x:longint):longint;
     15   begin
     16     exit(x and (-x));
     17   end;
     18 
     19 procedure swap(var a,b:longint);
     20   var c:longint;
     21   begin
     22     c:=a;
     23     a:=b;
     24     b:=c;
     25   end;
     26 
     27 function find(x:longint):longint;
     28   var l,r,m:longint;
     29   begin
     30     l:=1;
     31     r:=p;
     32     while l<=r do
     33     begin
     34       m:=(l+r) shr 1;
     35       if sa[m]=x then exit(m);
     36       if sa[m]>x then r:=m-1 else l:=m+1;
     37     end;
     38   end;
     39 
     40 procedure sort(l,r: longint);
     41   var i,j,x,y: longint;
     42   begin
     43     i:=l;
     44     j:=r;
     45     x:=a[(l+r) div 2];
     46     repeat
     47       while a[i]<x do inc(i);
     48       while x<a[j] do dec(j);
     49       if not(i>j) then
     50       begin
     51         swap(a[i],a[j]);
     52         inc(i);
     53         j:=j-1;
     54       end;
     55     until i>j;
     56     if l<j then sort(l,j);
     57     if i<r then sort(i,r);
     58  end;
     59 
     60 procedure update(i:longint);
     61   begin
     62     tree[i].s:=tree[tree[i].l].s+tree[tree[i].r].s;
     63   end;
     64 
     65 function build(l,r:longint):longint;
     66   var m,q:longint;
     67   begin
     68     inc(t);
     69     if l=r then exit(t)
     70     else begin
     71       q:=t;
     72       m:=(l+r) shr 1;
     73       tree[q].l:=build(l,m);
     74       tree[q].r:=build(m+1,r);
     75       exit(q);
     76     end;
     77   end;
     78 
     79 function add(l,r,y,z:longint):longint;
     80   var m,q:longint;
     81   begin
     82     inc(t);
     83     if l=r then
     84     begin
     85       tree[t].s:=tree[last].s+z;
     86       exit(t);
     87     end
     88     else begin
     89       q:=t;
     90       m:=(l+r) shr 1;
     91       if y<=m then
     92       begin
     93         tree[q].r:=tree[last].r;
     94         last:=tree[last].l;
     95         tree[q].l:=add(l,m,y,z);
     96       end
     97       else begin
     98         tree[q].l:=tree[last].l;
     99         last:=tree[last].r;
    100         tree[q].r:=add(m+1,r,y,z);
    101       end;
    102       update(q);
    103       exit(q);
    104     end;
    105   end;
    106 
    107 procedure insert(x,y,z:longint);
    108   begin
    109     while x<=n do
    110     begin
    111       last:=h[x];
    112       h[x]:=add(1,p,y,z);
    113       x:=x+lowbit(x);
    114     end;
    115   end;
    116 
    117 function getans(l,r,x:longint):longint;
    118   var m,i,s1,s2,j:longint;
    119   begin
    120     if l=r then exit(sa[l])
    121     else begin
    122       m:=(l+r) shr 1;
    123       s1:=0;
    124       s2:=0;
    125       for i:=1 to t1 do
    126       begin
    127         j:=tree[d1[i]].l;
    128         s1:=s1+tree[j].s;
    129       end;
    130       for i:=1 to t2 do
    131       begin
    132         j:=tree[d2[i]].l;
    133         s2:=s2+tree[j].s;
    134       end;
    135       if s2-s1>=x then
    136       begin
    137         for i:=1 to t1 do
    138           d1[i]:=tree[d1[i]].l;
    139         for i:=1 to t2 do
    140           d2[i]:=tree[d2[i]].l;
    141         exit(getans(l,m,x));
    142       end
    143       else begin
    144         for i:=1 to t1 do
    145           d1[i]:=tree[d1[i]].r;
    146         for i:=1 to t2 do
    147           d2[i]:=tree[d2[i]].r;
    148         x:=x-(s2-s1);
    149         exit(getans(m+1,r,x));
    150       end;
    151     end;
    152   end;
    153 
    154 function ask(l,r,x:longint):longint;
    155   var y:longint;
    156   begin
    157     t1:=0;
    158     t2:=0;
    159     y:=l-1;
    160     while y>0 do   //提取区间
    161     begin
    162       inc(t1);
    163       d1[t1]:=h[y];
    164       y:=y-lowbit(y);
    165     end;
    166     y:=r;
    167     while y>0 do
    168     begin
    169       inc(t2);
    170       d2[t2]:=h[y];
    171       y:=y-lowbit(y);
    172     end;
    173     exit(getans(1,p,x));
    174   end;
    175 
    176 begin
    177   readln(n,m);
    178   s:=n;
    179   for i:=1 to n do
    180   begin
    181     read(c[i]);
    182     a[i]:=c[i];
    183   end;
    184   readln;
    185   for i:=1 to m do
    186   begin
    187     read(q[i].wh);
    188     if q[i].wh='Q' then
    189       readln(q[i].l,q[i].r,q[i].x)
    190     else begin
    191       readln(q[i].l,q[i].x);
    192       inc(s);
    193       a[s]:=q[i].x;
    194     end;
    195   end;
    196   sort(1,s);
    197   p:=1;
    198   sa[1]:=a[1];
    199   for i:=2 to s do  //离散化
    200     if a[i]<>a[i-1] then
    201     begin
    202       inc(p);
    203       sa[p]:=a[i];
    204     end;
    205 
    206   h[0]:=build(1,p);
    207   for i:=1 to n do
    208   begin
    209     w[i]:=find(c[i]);
    210     insert(i,w[i],1);
    211   end;
    212   for i:=1 to m do
    213   begin
    214     if q[i].wh='Q' then
    215       writeln(ask(q[i].l,q[i].r,q[i].x))
    216     else begin
    217       x:=find(q[i].x);
    218       insert(q[i].l,w[q[i].l],-1);  //修改的两步
    219       insert(q[i].l,x,1);
    220       w[q[i].l]:=x;
    221     end;
    222   end;
    223 end.
    View Code
  • 相关阅读:
    [.NET控件]Telerik RadControls for ASP.NET AJAX 2008 Q1 net 2.0 Web.UI
    Cookie对象实战
    怎么样修改地址栏前面的图标
    进程管理工具可以下载使用
    怎样才能实现表格背景图片拉伸
    TabControl控件的最佳实践,可以把一个窗体和用户控件添加进来
    flex+eclipse
    为gridview“删除”列添加确认对话框的方法
    触发器deleted 表和 inserted 表详解!!!
    ExtJs的使用
  • 原文地址:https://www.cnblogs.com/phile/p/4473094.html
Copyright © 2011-2022 走看看