zoukankan      html  css  js  c++  java
  • 【BZOJ1901】Dynamic Rankings(树套树,树状数组,主席树)

    题意:给定一个N个数的序列,要求维护一个数据结构支持以下两种操作:

    1:将第X个数改成Y

    2:查询第X到第Y个数里第K小的数是多少

    n,m<=10000,a[i]<=10^9

    思路:单点修改版本的主席树

    对于没有修改的主席树,我们直接在对应的节点上每个点继承上个点的状态,再用链表创建logn个点来表示这个数对t数组的修改

    而单点修改不可能把后面的前缀和都加上logn个点

    所以就利用树状数组的思想

    t是一个树状数组,里面的每个点都是一棵主席树

    更改时没有区别

    询问时最多可能有logn段区间相减

    时间复杂度(Nlogn^2)

      1 var t:array[0..4000000]of record
      2 l,r,s:longint;
      3 end;
      4 a,b,root,hash,left,right,flag:array[0..40000]of longint;
      5 d:array[1..40000,1..3]of longint;
      6 n,m,i,j,q,u,cnt,la,lb,s,tmp:longint;
      7 ch:string;
      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 function find(k:longint):longint;
     16 var l,r,mid:longint;
     17 begin
     18 l:=1; r:=u;
     19 while l<=r do
     20 begin
     21 mid:=(l+r)>>1;
     22 if hash[mid]=k then exit(mid);
     23 if hash[mid]<k then l:=mid+1
     24 else r:=mid-1;
     25 end;
     26 end;
     27 
     28 procedure qsort(l,r:longint);
     29 var i,j,mid:longint;
     30 begin
     31 i:=l; j:=r; mid:=b[(l+r)>>1];
     32 repeat
     33 while mid>b[i] do inc(i);
     34 while mid<b[j] do dec(j);
     35 if i<=j then
     36 begin
     37 swap(b[i],b[j]);
     38 inc(i); dec(j);
     39 end;
     40 until i>j;
     41 if l<j then qsort(l,j);
     42 if i<r then qsort(i,r);
     43 end;
     44 
     45 function lowbit(x:longint):longint;
     46 begin
     47 exit(x and (-x));
     48 end;
     49 
     50 
     51 procedure update(l,r:longint;var p:longint;v,x:longint);
     52 var mid:longint;
     53 begin
     54 inc(cnt); t[cnt]:=t[p];
     55 p:=cnt; t[p].s:=t[p].s+x;
     56 if l=r then exit;
     57 mid:=(l+r)>>1;
     58 if v<=mid then update(l,mid,t[p].l,v,x)
     59 else update(mid+1,r,t[p].r,v,x);
     60 end;
     61 
     62 function query(l,r,k:longint):longint;
     63 var s1,s2,i,mid:longint;
     64 begin
     65 if l=r then exit(l);
     66 s1:=0; s2:=0;
     67 for i:=1 to la do s1:=s1+t[t[left[i]].l].s;
     68 for i:=1 to lb do s2:=s2+t[t[right[i]].l].s;
     69 mid:=(l+r)>>1;
     70 if s2-s1>=k then
     71 begin
     72 for i:=1 to la do left[i]:=t[left[i]].l;
     73 for i:=1 to lb do right[i]:=t[right[i]].l;
     74 exit(query(l,mid,k));
     75 end
     76 else
     77 begin
     78 for i:=1 to la do left[i]:=t[left[i]].r;
     79 for i:=1 to lb do right[i]:=t[right[i]].r;
     80 exit(query(mid+1,r,k-(s2-s1)));
     81 end;
     82 end;
     83 
     84 
     85 begin
     86 assign(input,'data.in'); reset(input);
     87 assign(output,'bzoj1901.out'); rewrite(output);
     88 readln(n,m);
     89 q:=0;
     90 for i:=1 to n do
     91 begin
     92 read(a[i]);
     93 inc(q); b[q]:=a[i];
     94 end;
     95 readln;
     96 for i:=1 to m do
     97 begin
     98 readln(ch); s:=0;
     99 if ch[1]='C' then
    100 begin
    101 inc(q);
    102 for j:=3 to length(ch) do
    103 begin
    104 if ch[j]=' ' then begin inc(s); continue; end;
    105 d[i,s+1]:=d[i,s+1]*10+ord(ch[j])-ord('0');
    106 end;
    107 b[q]:=d[i,2];
    108 end;
    109 if ch[1]='Q' then
    110 begin
    111 flag[i]:=1;
    112 for j:=3 to length(ch) do
    113 begin
    114 if ch[j]=' ' then begin inc(s); continue; end;
    115 d[i,s+1]:=d[i,s+1]*10+ord(ch[j])-ord('0');
    116 end;
    117 end;
    118 end;
    119 qsort(1,q);
    120 hash[1]:=b[1]; u:=1;
    121 for i:=2 to q do
    122 if b[i]<>b[i-1] then begin inc(u); hash[u]:=b[i]; end;
    123 
    124 for i:=1 to n do
    125 begin
    126 tmp:=find(a[i]);
    127 j:=i;
    128 while j<=n do
    129 begin
    130 update(1,u,root[j],tmp,1);
    131 j:=j+lowbit(j);
    132 end;
    133 end;
    134 
    135 for i:=1 to m do
    136 if flag[i]=1 then
    137 begin
    138 la:=0; lb:=0; j:=d[i,1]-1;
    139 while j>0 do
    140 begin
    141 inc(la); left[la]:=root[j];
    142 j:=j-lowbit(j);
    143 end;
    144 j:=d[i,2];
    145 while j>0 do
    146 begin
    147 inc(lb); right[lb]:=root[j];
    148 j:=j-lowbit(j);
    149 end;
    150 writeln(hash[query(1,u,d[i,3])]);
    151 end
    152 else
    153 begin
    154 tmp:=find(a[d[i,1]]);
    155 j:=d[i,1];
    156 while j<=n do
    157 begin
    158 update(1,u,root[j],tmp,-1);
    159 j:=j+lowbit(j);
    160 end;
    161 tmp:=find(d[i,2]);
    162 j:=d[i,1];
    163 while j<=n do
    164 begin
    165 update(1,u,root[j],tmp,1);
    166 j:=j+lowbit(j);
    167 end;
    168 a[d[i,1]]:=d[i,2];
    169 end;
    170 close(input);
    171 close(output);
    172 end.
    173 
    174  
    175 
    176  

     UPD(2018.9.21):C++

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<string>
      4 #include<cmath>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<map>
      8 #include<set>
      9 #include<queue>
     10 #include<vector>
     11 using namespace std;
     12 typedef long long ll;
     13 typedef unsigned int uint;
     14 typedef unsigned long long ull;
     15 typedef pair<int,int> PII;
     16 typedef vector<int> VI;
     17 #define fi first
     18 #define se second 
     19 #define MP make_pair
     20 #define N   3100000
     21 #define M   30000
     22 #define MOD 1000000007
     23 #define eps 1e-8 
     24 #define pi acos(-1)
     25 #define oo 1e9
     26 
     27 char ch[10];
     28 struct arr
     29 {
     30     int l,r,s;
     31 }t[N];
     32 int a[M],b[M],root[M],
     33     L[30],R[30],A[M],B[M],K[M],flag[M],
     34     n,m,cnt,l1,l2,mx; 
     35 
     36 int read()
     37 { 
     38    int v=0,f=1;
     39    char c=getchar();
     40    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     41    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     42    return v*f;
     43 }
     44 
     45 int lowbit(int x)
     46 {
     47     return x&(-x);
     48 }
     49 
     50 int lsh(int x)
     51 {
     52     int l=1;
     53     int r=mx;
     54     while(l<=r)
     55     {
     56         int mid=(l+r)>>1;
     57         if(b[mid]==x) return mid;
     58         if(b[mid]<x) l=mid+1;
     59          else r=mid-1;
     60     }
     61 }
     62 
     63 
     64 void update(int l,int r,int x,int v,int &p)
     65 {
     66     t[++cnt].l=t[p].l;
     67     t[cnt].r=t[p].r;
     68     t[cnt].s=t[p].s;
     69     p=cnt;
     70     t[p].s+=v;
     71     if(l==r) return;
     72     int mid=(l+r)>>1;
     73     if(x<=mid) update(l,mid,x,v,t[p].l);
     74      else update(mid+1,r,x,v,t[p].r);
     75 }
     76     
     77 int query(int l,int r,int k)
     78 {
     79     //printf("%d %d %d ",l,r,k);
     80     if(l==r) return l;
     81     int s1=0;
     82     int s2=0;
     83     for(int i=1;i<=l1;i++) s1+=t[t[L[i]].l].s;
     84     for(int i=1;i<=l2;i++) s2+=t[t[R[i]].l].s;
     85     int tmp=s2-s1;
     86     //printf("%d
    ",tmp);
     87     int mid=(l+r)>>1;
     88     if(tmp>=k)
     89     {
     90          for(int i=1;i<=l1;i++) L[i]=t[L[i]].l;
     91          for(int i=1;i<=l2;i++) R[i]=t[R[i]].l;
     92          return query(l,mid,k);
     93     }
     94      else
     95      {
     96          for(int i=1;i<=l1;i++) L[i]=t[L[i]].r;
     97          for(int i=1;i<=l2;i++) R[i]=t[R[i]].r;
     98          return query(mid+1,r,k-tmp);
     99      }
    100 }
    101          
    102     
    103 int main()
    104 {
    105     freopen("data.in","r",stdin);
    106     freopen("bzoj1901.out","w",stdout);
    107     int q;
    108     scanf("%d%d",&n,&q);
    109     m=0;
    110     for(int i=1;i<=n;i++) 
    111     {
    112         scanf("%d",&a[i]);
    113         b[++m]=a[i];
    114     }
    115     for(int i=1;i<=q;i++)
    116     {
    117         scanf("%s",ch);
    118         scanf("%d%d",&A[i],&B[i]);
    119         if(ch[0]=='Q'){scanf("%d",&K[i]); flag[i]=1;}
    120          else b[++m]=B[i];
    121     }
    122     sort(b+1,b+m+1);
    123     cnt=0;
    124     mx=1;
    125     for(int i=2;i<=m;i++)
    126      if(b[i]!=b[mx]) b[++mx]=b[i];
    127     for(int i=1;i<=n;i++)
    128     {
    129         int tmp=lsh(a[i]);
    130         int j=i;
    131         while(j<=n)
    132         {
    133              update(1,mx,tmp,1,root[j]);
    134              j+=lowbit(j);
    135         }
    136     }
    137     
    138     for(int i=1;i<=q;i++)
    139      if(flag[i])
    140      {
    141          l1=0; l2=0; A[i]--;
    142          int j=A[i];
    143          while(j)
    144          {
    145              L[++l1]=root[j];
    146              j-=lowbit(j);
    147          }
    148          j=B[i];
    149          while(j)
    150          {
    151              R[++l2]=root[j];
    152              j-=lowbit(j);
    153          }
    154          printf("%d
    ",b[query(1,mx,K[i])]);
    155      }
    156      else 
    157      {
    158          int x=lsh(a[A[i]]);
    159          int j=A[i];
    160          while(j<=n)
    161          {
    162              update(1,mx,x,-1,root[j]);
    163              j+=lowbit(j);
    164          }
    165          a[A[i]]=B[i];
    166          x=lsh(B[i]);
    167          j=A[i];
    168          while(j<=n)
    169          {
    170              update(1,mx,x,1,root[j]);
    171             j+=lowbit(j);
    172          }
    173      }
    174          
    175         
    176 }
    177 
    178 
    179             
    180         
  • 相关阅读:
    android 获取字体宽高
    android 渐变
    android 拖动按钮
    android 模拟器使用
    android 启动其它apk
    How to solve Error: This attribute must be localized. 两种方式
    Chirp用音频 传输文件
    android 打开指定网页
    防止apk被反编译
    iphone 滑块制作
  • 原文地址:https://www.cnblogs.com/myx12345/p/6151440.html
Copyright © 2011-2022 走看看