题目链接
先写了一个BIT套主席树,后来觉得树套树好写又写了一个树套树
因为没有离散化所以树套树要慢一些QAQ
BIT套主席树
第一次写,参考了一下hzwer的代码%%%Orz
跟主席树不同的就是查询和修改都像BIT一样,要修改log2n颗树的信息
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 void inin(int &ret) 27 { 28 ret=0;int f=0;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 31 ret=f?-ret:ret; 32 } 33 int n,m,ed,ch[3000010][2],sum[3000010],root[20020]; 34 inline int lowbit(int x){return x&-x;} 35 int v[20020],num[20020],A[20020],B[20020],K[20020],top; 36 int hash[20020],tot,ls[33],rs[33],a,b; 37 int HASH(int x) 38 { 39 int l=1,r=tot,mid; 40 while(l<=r){mid=(l+r)>>1;if(hash[mid]<x)l=mid+1;else r=mid-1;} 41 return l; 42 } 43 void update(int last,int l,int r,int &y,int wei,int x) 44 { 45 y=++ed; 46 sum[y]=sum[last]+x,ch[y][0]=ch[last][0],ch[y][1]=ch[last][1]; 47 if(l==r)return ; 48 int mid=(l+r)>>1; 49 if(wei<=mid)update(ch[last][0],l,mid,ch[y][0],wei,x); 50 else update(ch[last][1],mid+1,r,ch[y][1],wei,x); 51 } 52 int query(int l,int r,int k) 53 { 54 if(l==r)return l; 55 int sum1=0,sum2=0; 56 re(i,1,a)sum1+=sum[ch[ls[i]][0]]; 57 re(i,1,b)sum2+=sum[ch[rs[i]][0]]; 58 int mid=(l+r)>>1; 59 if(sum2-sum1>=k) 60 { 61 re(i,1,a)ls[i]=ch[ls[i]][0]; 62 re(i,1,b)rs[i]=ch[rs[i]][0]; 63 return query(l,mid,k); 64 } 65 else 66 { 67 re(i,1,a)ls[i]=ch[ls[i]][1]; 68 re(i,1,b)rs[i]=ch[rs[i]][1]; 69 return query(mid+1,r,k+sum1-sum2); 70 } 71 } 72 void add(int i,int x,int xx) 73 { 74 for(int j=i;j<=n;j+=lowbit(j)) 75 update(root[j],1,tot,root[j],x,xx); 76 } 77 int query(int i) 78 { 79 a=b=0; 80 A[i]--; 81 for(int j=A[i];j;j-=lowbit(j))ls[++a]=root[j]; 82 for(int j=B[i];j;j-=lowbit(j))rs[++b]=root[j]; 83 return hash[query(1,tot,K[i])]; 84 } 85 int CSC() 86 { 87 char s[3]; 88 inin(n),inin(m); 89 re(i,1,n)inin(v[i]),num[i]=v[i]; 90 top=n; 91 re(i,1,m) 92 { 93 strin(s); 94 inin(A[i]),inin(B[i]); 95 if(s[0]=='Q')inin(K[i]); 96 else num[++top]=B[i]; 97 } 98 sort(num,num+top+1); 99 hash[++tot]=num[1];int wei; 100 re(i,2,top)if(num[i]!=num[i-1])hash[++tot]=num[i]; 101 re(i,1,n)wei=HASH(v[i]),add(i,wei,1); 102 re(i,1,m)if(K[i])printf("%d\n",query(i)); 103 else 104 { 105 wei=HASH(v[A[i]]); 106 add(A[i],wei,-1); 107 v[A[i]]=B[i]; 108 wei=HASH(B[i]); 109 add(A[i],wei,1); 110 } 111 return 0; 112 }
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 void inin(int &ret) 27 { 28 ret=0;int f=0;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 31 ret=f?-ret:ret; 32 } 33 cint inf=1000000000; 34 int ch[2000010][2],w[2000010],s[2000010],c[2000010],rr[2000010],ed; 35 struct segtree 36 { 37 int l,r,root; 38 segtree(){root=0;} 39 void maintain(int k){if(k)s[k]=c[k]+s[ch[k][0]]+s[ch[k][1]];} 40 void rotate(int &k,int d) 41 { 42 int p=ch[k][d^1]; 43 ch[k][d^1]=ch[p][d]; 44 ch[p][d]=k;s[p]=s[k]; 45 maintain(k),k=p; 46 } 47 private: 48 void add(int &k,const int &x) 49 { 50 if(!k) 51 { 52 k=++ed,w[k]=x,rr[k]=rand();s[k]=c[k]=1;ch[k][0]=ch[k][1]=0; 53 return ; 54 }s[k]++; 55 if(x==w[k]){c[k]++;return ;} 56 int d=x>w[k];add(ch[k][d],x); 57 if(rr[ch[k][d]]<rr[k])rotate(k,d^1); 58 } 59 bool del(int &k,const int &x) 60 { 61 if(!k)return 0; 62 if(x==w[k]) 63 { 64 if(c[k]>1){c[k]--,s[k]--;return 1;} 65 if(!ch[k][0]){k=ch[k][1];return 1;} 66 if(!ch[k][1]){k=ch[k][0];return 1;} 67 if(rr[ch[k][0]]<rr[ch[k][1]])rotate(k,1); 68 else rotate(k,0); 69 return del(k,x); 70 } 71 int d=x>w[k]; 72 if(del(ch[k][d],x)) 73 { 74 s[k]--; 75 return 1; 76 } 77 else return 0; 78 } 79 int findrank(int k,const int &x) 80 { 81 if(!k)return 0; 82 int pp=(ch[k][0]?s[ch[k][0]]:0); 83 if(x==w[k])return pp; 84 if(x>w[k])return pp+c[k]+findrank(ch[k][1],x); 85 return findrank(ch[k][0],x); 86 } 87 int findwei(int k,const int &x) 88 { 89 if(!k)return 0; 90 int pp=(ch[k][0]?s[ch[k][0]]:0); 91 if(x<=pp)return findwei(ch[k][0],x); 92 if(x>pp+c[k])return findwei(ch[k][1],x-pp-c[k]); 93 return w[k]; 94 95 } 96 void findqian(int k,const int &x,int &ans) 97 { 98 if(!k)return ; 99 if(x>w[k])ans=w[k],findqian(ch[k][1],x,ans); 100 else findqian(ch[k][0],x,ans); 101 } 102 void findhou(int k,const int &x,int &ans) 103 { 104 if(!k)return ; 105 if(x<w[k])ans=w[k],findhou(ch[k][0],x,ans); 106 else findhou(ch[k][1],x,ans); 107 } 108 public: 109 void add(int x){add(root,x);} 110 void del(int x){del(root,x);} 111 int findrank(int x){return findrank(root,x);} 112 int findwei(int x){return findwei(root,x);} 113 int findqian(int x) 114 { 115 int ans=0;findqian(root,x,ans); 116 return ans; 117 } 118 int findhou(int x) 119 { 120 int ans=0;findhou(root,x,ans); 121 return !ans?inf:ans; 122 } 123 }t[40040]; 124 int n,m,a[10010]; 125 void build(int k,int l,int r,int x) 126 { 127 t[k].l=l,t[k].r=r,t[k].add(a[x]); 128 if(l==r)return ;int mid=(l+r)>>1; 129 if(x<=mid)build(k<<1,l,mid,x); 130 else build(k<<1|1,mid+1,r,x); 131 } 132 int findrank(int k,int l,int r,int x) 133 { 134 if(t[k].l>=l&&t[k].r<=r)return t[k].findrank(x); 135 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 136 if(r<=mid)return findrank(p1,l,r,x); 137 if(l>mid)return findrank(p2,l,r,x); 138 return findrank(p1,l,r,x)+findrank(p2,l,r,x); 139 } 140 int findqian(int k,int l,int r,int x) 141 { 142 if(t[k].l>=l&&t[k].r<=r)return t[k].findqian(x); 143 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 144 if(r<=mid)return findqian(p1,l,r,x); 145 if(l>mid)return findqian(p2,l,r,x); 146 return max(findqian(p1,l,r,x),findqian(p2,l,r,x)); 147 } 148 int findhou(int k,int l,int r,int x) 149 { 150 if(t[k].l>=l&&t[k].r<=r)return t[k].findhou(x); 151 int mid=(t[k].l+t[k].r)>>1,p1=k<<1,p2=p1|1; 152 if(r<=mid)return findhou(p1,l,r,x); 153 if(l>mid)return findhou(p2,l,r,x); 154 return min(findhou(p1,l,r,x),findhou(p2,l,r,x)); 155 } 156 int findwei(int l,int r,int x) 157 { 158 int ll=0,rr=inf,mid,ans; 159 while(ll<=rr) 160 { 161 mid=(ll+rr)>>1; 162 int rank=findrank(1,l,r,mid)+1; 163 if(rank<=x)ans=mid,ll=mid+1;else rr=mid-1; 164 } 165 return findqian(1,l,r,ans+1); 166 } 167 void change(int k,int x,int w) 168 { 169 t[k].del(a[x]),t[k].add(w); 170 if(t[k].l==t[k].r)return ; 171 int mid=(t[k].l+t[k].r)>>1; 172 if(x<=mid)change(k<<1,x,w); 173 else change(k<<1|1,x,w); 174 } 175 int CSC() 176 { 177 inin(n);inin(m); 178 re(i,1,n)inin(a[i]),build(1,1,n,i); 179 re(i,1,m) 180 { 181 char s[3]; 182 strin(s);int q,w,e; 183 if(s[0]=='Q') 184 { 185 inin(q),inin(w),inin(e); 186 printf("%d\n",findwei(q,w,e)); 187 } 188 else 189 { 190 inin(q),inin(w); 191 change(1,q,w); 192 a[q]=w; 193 } 194 } 195 return 0; 196 }