码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3731: Gty的超级妹子树

时间:2015-01-25 22:32:09      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3731

题解:

多了一个操作:删边。

如果x与fa[x]不在同一块,直接把这条边去掉即可。

否则 我们把x以下的点全部划入新的以x的根的块内,然后把b[fa[x]]往下的边断开并连到b[x]上。

这些实现的时候都很有技巧性,具体可以看代码。

然后发现代码长了就很容易忘打XX,而且心里还会产生程序很对的错觉。。。

不断调整块的大小最后调到了sqrt(10*n*logn)然后就rank1了。。。比写treap的快了。。。

技术分享
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<iostream>
  7 #include<vector>
  8 #include<map>
  9 #include<set>
 10 #include<queue>
 11 #include<string>
 12 #define inf 1000000000
 13 #define maxn 200000+5
 14 #define maxm 100000+5
 15 #define eps 1e-10
 16 #define ll long long
 17 #define pa pair<int,int>
 18 #define for0(i,n) for(int i=0;i<=(n);i++)
 19 #define for1(i,n) for(int i=1;i<=(n);i++)
 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 22 #define for4(i,k,x) for(int i=head[k][x],y=e[k][i].go;i;i=e[k][i].next,y=e[k][i].go)
 23 #define mod 1000000007
 24 using namespace std;
 25 inline int read()
 26 {
 27     int x=0,f=1;char ch=getchar();
 28     while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
 29     while(ch>=0&&ch<=9){x=10*x+ch-0;ch=getchar();}
 30     return x*f;
 31 }
 32 struct rec
 33 {
 34     vector<int>a;
 35     inline void insert(int x)
 36     {
 37         a.insert(lower_bound(a.begin(),a.end(),x+1),x);
 38     }
 39     inline void erase(int x)
 40     {
 41         a.erase(lower_bound(a.begin(),a.end(),x));
 42     }
 43     inline void modify(int x,int y)
 44     {
 45         erase(x);insert(y);
 46     }
 47     inline int query(int x)
 48     {
 49         return a.size()-(upper_bound(a.begin(),a.end(),x)-a.begin()+1)+1;
 50     }
 51 }s[maxn];
 52 int n,m,ans,size,cnt,top[maxn],tot[2],head[2][maxn],a[maxn],fa[2][maxn],b[maxn],c[maxn],d[maxn];
 53 struct edge{int go,next;}e[2][3*maxn];
 54 inline void add(int k,int x,int y)
 55 {
 56     e[k][++tot[k]]=(edge){y,head[k][x]};head[k][x]=tot[k];
 57 }
 58 inline void dfs(int x)
 59 {
 60     for4(i,0,x)if(y!=fa[0][x])
 61     {
 62         fa[0][y]=x;
 63         if(s[b[x]].a.size()<size)s[b[y]=b[x]].insert(a[y]);
 64         else top[b[y]=++cnt]=y,s[cnt].insert(a[y]),add(1,b[x],b[y]),fa[1][b[y]]=b[x];
 65         dfs(y);
 66     }
 67 }
 68 inline void query2(int x,int w)
 69 {
 70     ans+=s[x].query(w);
 71     for4(i,1,x)if(fa[1][y]==x)query2(y,w);
 72 }
 73 inline void query1(int x,int w)
 74 {
 75     if(a[x]>w)ans++;
 76     for4(i,0,x)if(y!=fa[0][x]&&fa[0][y]==x){if(top[b[y]]==y)query2(b[y],w);else query1(y,w);}
 77 }
 78 inline void find(int x)
 79 {
 80     c[++c[0]]=x;
 81     for4(i,0,x)if(y!=fa[0][x]&&fa[0][y]==x)
 82     {
 83         if(b[y]==b[x])find(y);
 84         else d[++d[0]]=b[y];
 85     }
 86 }
 87 int main()
 88 {
 89     freopen("input.txt","r",stdin);
 90     freopen("output.txt","w",stdout);
 91     n=read();
 92     for1(i,n-1){int x=read(),y=read();add(0,x,y);add(0,y,x);}
 93     for1(i,n)a[i]=read();
 94     s[b[1]=top[1]=cnt=1].insert(a[1]);
 95     size=sqrt(10*n*log2(n));
 96     dfs(1);
 97     m=read();
 98     while(m--)
 99     {
100         int op=read();
101         if(op==3)
102         {
103             int x=read()^ans;
104             if(b[x]!=b[fa[0][x]])fa[0][x]=0,fa[1][b[x]]=0;
105             else
106             {
107                 find(x);
108                 top[b[x]=++cnt]=x;
109                 for1(i,c[0])
110                 {
111                  s[b[fa[0][x]]].erase(a[c[i]]);
112                  s[b[x]].insert(a[c[i]]);
113                  b[c[i]]=b[x];
114                 }
115                 for1(i,d[0])add(1,b[x],d[i]),fa[1][d[i]]=b[x];
116                 fa[0][x]=c[0]=d[0]=0;
117             }
118         }
119         else
120         {
121            int x=read()^ans,y=read()^ans;
122            if(op==0)
123            {
124             ans=0;
125             if(top[b[x]]!=x)query1(x,y);
126             else query2(b[x],y);
127             printf("%d\n",ans);
128            }else if(op==1)
129            {
130             s[b[x]].modify(a[x],y);
131             a[x]=y;
132            }else if(op==2)
133            {
134             a[++n]=y;add(0,x,n);fa[0][n]=x;
135             if(s[b[x]].a.size()<size)s[b[n]=b[x]].insert(a[n]);
136             else top[b[n]=++cnt]=n,s[cnt].insert(a[n]),add(1,b[x],b[n]),fa[1][b[n]]=b[x];
137            }
138         }
139     }
140     return 0;
141 }
View Code

 

BZOJ3731: Gty的超级妹子树

标签:

原文地址:http://www.cnblogs.com/zyfzyf/p/4249018.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!