bzoj1901 Zju2112 Dynamic Rankings

题目链接

先写了一个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 }
BIT套主席树
  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 }
线段树套平衡树

 

posted @ 2016-02-02 14:27  HugeGun  阅读(241)  评论(0编辑  收藏  举报