BZOJ 1901 树状数组+函数式线段树
题解:
带单点更新的区间第k大~
函数式线段树秒杀了~
与不带修改的函数式线段树唯一不同的在于线段树中的每个结点维护的都是这个位置的结点的树状数组值~
然后自己随便怎么胡搞啊神马的就nlog^2n了~
View Code
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 7 #define N 110040 8 #define lowbit(x) x&-x 9 10 using namespace std; 11 12 int h[N],ls[N<<5],rs[N<<5],sum[N<<5]; 13 int cnt,n,m,gs,num; 14 int a[N],bh[N]; 15 int dat[N][4],ln[N],rn[N],lc,rc; 16 17 inline int newnode(int s,int l,int r) 18 { 19 ++cnt; sum[cnt]=s; ls[cnt]=l; rs[cnt]=r; 20 return cnt; 21 } 22 23 inline void build(int l,int r,int &rt) 24 { 25 rt=newnode(0,0,0); 26 if(l==r) return; 27 int mid=(l+r)>>1; 28 build(l,mid,ls[rt]); 29 build(mid+1,r,rs[rt]); 30 } 31 32 inline void updata(int last,int pos,int val,int l,int r,int &rt) 33 { 34 rt=newnode(sum[last]+val,ls[last],rs[last]); 35 if(l==r) return; 36 int mid=(l+r)>>1; 37 if(pos<=mid) updata(ls[last],pos,val,l,mid,ls[rt]); 38 else updata(rs[last],pos,val,mid+1,r,rs[rt]); 39 } 40 41 inline void modify(int x,int pos,int val) 42 { 43 int tmp; 44 while(x<=n) 45 { 46 updata(h[x],pos,val,1,num,tmp); 47 h[x]=tmp; 48 x+=lowbit(x); 49 } 50 } 51 52 inline int query(int l,int r,int k) 53 { 54 if(l==r) return l; 55 int tr=0,tl=0; 56 for(int i=1;i<=rc;i++) tr+=sum[ls[rn[i]]]; 57 for(int i=1;i<=lc;i++) tl+=sum[ls[ln[i]]]; 58 tr-=tl; 59 int mid=(l+r)>>1; 60 if(k<=tr) 61 { 62 for(int i=1;i<=rc;i++) rn[i]=ls[rn[i]]; 63 for(int i=1;i<=lc;i++) ln[i]=ls[ln[i]]; 64 return query(l,mid,k); 65 } 66 else 67 { 68 for(int i=1;i<=rc;i++) rn[i]=rs[rn[i]]; 69 for(int i=1;i<=lc;i++) ln[i]=rs[ln[i]]; 70 return query(mid+1,r,k-tr); 71 } 72 } 73 74 inline int getans(int l,int r,int k) 75 { 76 rc=lc=0; 77 while(r) 78 { 79 rn[++rc]=h[r]; 80 r-=lowbit(r); 81 } 82 while(l) 83 { 84 ln[++lc]=h[l]; 85 l-=lowbit(l); 86 } 87 return query(1,num,k); 88 } 89 90 inline void read() 91 { 92 scanf("%d%d",&n,&m); 93 for(int i=1;i<=n;i++) 94 { 95 scanf("%d",&a[i]); 96 bh[++gs]=a[i]; 97 } 98 char str[4]; 99 for(int i=1;i<=m;i++) 100 { 101 scanf("%s",str); 102 if(str[0]=='Q') 103 { 104 dat[i][0]=0; 105 for(int j=1;j<=3;j++) scanf("%d",&dat[i][j]); 106 } 107 else 108 { 109 dat[i][0]=1; 110 scanf("%d%d",&dat[i][1],&dat[i][2]); 111 bh[++gs]=dat[i][2]; 112 } 113 } 114 } 115 116 inline void go() 117 { 118 sort(bh+1,bh+1+gs); 119 num=unique(bh+1,bh+1+gs)-bh-1; 120 for(int i=1;i<=n;i++) a[i]=lower_bound(bh+1,bh+1+num,a[i])-bh; 121 build(1,num,h[0]); 122 for(int i=1;i<=n;i++) modify(i,a[i],1); 123 for(int i=1;i<=m;i++) 124 { 125 if(dat[i][0]==0) printf("%d\n",bh[getans(dat[i][1]-1,dat[i][2],dat[i][3])]); 126 else 127 { 128 int pos=lower_bound(bh+1,bh+1+num,dat[i][2])-bh; 129 modify(dat[i][1],a[dat[i][1]],-1); 130 a[dat[i][1]]=pos; 131 modify(dat[i][1],a[dat[i][1]],1); 132 } 133 } 134 } 135 136 int main() 137 { 138 read(),go(); 139 return 0; 140 }
没有人能阻止我前进的步伐,除了我自己!