【带修改的主席树】BZOJ1901-Dynamic Rankings
稍后整理笔记。这题数据范围好像有点问题?
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<algorithm> 6 #define lson l,m 7 #define rson m+1,r 8 using namespace std; 9 const int MAXN=60000+50; 10 int n,q,tot,m,d; 11 struct node 12 { 13 int l,r,k,Q; 14 }op[MAXN]; 15 int a[MAXN<<1],hash[MAXN<<1],T[MAXN<<1],S[MAXN<<1],use[MAXN<<1]; 16 int L[MAXN<<5],R[MAXN<<5],sum[MAXN<<5]; 17 18 int lowbit(int x) 19 { 20 return (x&(-x)); 21 } 22 23 int build(int l,int r) 24 { 25 int rt=++tot; 26 sum[rt]=0; 27 if (l!=r) 28 { 29 int m=(l+r)>>1; 30 L[rt]=build(lson); 31 R[rt]=build(rson); 32 } 33 return rt; 34 } 35 36 int update(int pre,int l,int r,int x,int op) 37 { 38 int rt=++tot; 39 L[rt]=L[pre],R[rt]=R[pre],sum[rt]=sum[pre]+op; 40 if (l<r) 41 { 42 int m=(l+r)>>1; 43 if (x<=m) L[rt]=update(L[pre],lson,x,op); 44 else R[rt]=update(R[pre],rson,x,op); 45 } 46 return rt; 47 } 48 49 int Sum(int x) 50 { 51 int ret=0; 52 while (x>0) 53 { 54 ret+=sum[L[use[x]]]; 55 x-=lowbit(x); 56 } 57 return ret; 58 } 59 60 int query(int Sl,int Sr,int Tl,int Tr,int l,int r,int k) 61 { 62 if (l==r) return l; 63 int m=(l+r)>>1; 64 int tmp=Sum(Sr)-Sum(Sl)+sum[L[Tr]]-sum[L[Tl]]; 65 if (tmp>=k) 66 { 67 for (int i=Sl;i;i-=lowbit(i)) use[i]=L[use[i]]; 68 for (int i=Sr;i;i-=lowbit(i)) use[i]=L[use[i]]; 69 return query(Sl,Sr,L[Tl],L[Tr],lson,k); 70 } 71 else 72 { 73 for (int i=Sl;i;i-=lowbit(i)) use[i]=R[use[i]]; 74 for (int i=Sr;i;i-=lowbit(i)) use[i]=R[use[i]]; 75 return query(Sl,Sr,R[Tl],R[Tr],rson,k-tmp); 76 } 77 } 78 79 void modify(int x,int p,int delta) 80 { 81 while (x<=n) 82 { 83 S[x]=update(S[x],1,d,p,delta); 84 x+=lowbit(x); 85 } 86 } 87 88 void init() 89 { 90 tot=0; 91 m=0; 92 d=0; 93 scanf("%d%d",&n,&q); 94 for (int i=1;i<=n;i++) scanf("%d",&a[i]),hash[++m]=a[i]; 95 for (int i=0;i<q;i++) 96 { 97 char s[10]; 98 scanf("%s",s); 99 if (s[0]=='Q') scanf("%d%d%d",&op[i].l,&op[i].r,&op[i].k),op[i].Q=1; 100 else 101 { 102 scanf("%d%d",&op[i].l,&op[i].r); 103 op[i].Q=0; 104 hash[++m]=op[i].r; 105 } 106 } 107 /*因为修改后的数可能不在初始几个数的范围内,故要先输入完查询*/ 108 109 sort(hash+1,hash+m+1); 110 d=unique(hash+1,hash+1+m)-hash-1; 111 112 T[0]=build(1,d);//T表示每一步T树的树根 113 for (int i=1;i<=n;i++) 114 { 115 int x=lower_bound(hash+1,hash+d+1,a[i])-hash; 116 T[i]=update(T[i-1],1,d,x,1); 117 } 118 119 for (int i=1;i<=n;i++) S[i]=T[0]; 120 } 121 122 void solve() 123 { 124 125 for (int i=0;i<q;i++) 126 { 127 if (op[i].Q) 128 { 129 for (int j=op[i].l-1;j;j-=lowbit(j)) use[j]=S[j]; 130 for (int j=op[i].r;j;j-=lowbit(j)) use[j]=S[j]; 131 int ans=query(op[i].l-1,op[i].r,T[op[i].l-1],T[op[i].r],1,d,op[i].k); 132 printf("%d\n",hash[ans]); 133 } 134 else 135 { 136 int x=lower_bound(hash+1,hash+d+1,a[op[i].l])-hash; 137 int y=lower_bound(hash+1,hash+d+1,op[i].r)-hash; 138 modify(op[i].l,x,-1); 139 modify(op[i].l,y,1); 140 a[op[i].l] =op[i].r; 141 } 142 } 143 } 144 145 int main() 146 { 147 init(); 148 solve(); 149 return 0; 150 }