BZOJ3720: Gty的妹子树

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

题解:

传说中的块状树。。。

和链剖思想差不多,能塞到父亲块里的就塞,否则自己新开一块。

只是比较纠结树分块究竟用什么?如果是树上莫队的话好像不能这么分?

被菊花卡死?

然后我们就每个块暴力维护信息。刚开始以为set就行了,到了写查询的时候发现尼玛set是不能维护名次的T_T

还是老老实实写线性表吧。

块开sqrt(n*log2n)比sqrt(n)快一倍

代码:

  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 60000+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     int a[1500],n;
 35     inline void insert(int x)
 36     {
 37         int i=++n;
 38         for(;i>1&&a[i-1]>x;i--)a[i]=a[i-1];
 39         a[i]=x;
 40     }
 41     inline void modify(int x,int y)
 42     {
 43         int i=lower_bound(a+1,a+n+1,x)-a;
 44         for(;i<n&&a[i+1]<y;i++)a[i]=a[i+1];
 45         for(;i>1&&a[i-1]>y;i--)a[i]=a[i-1];
 46         a[i]=y;
 47     }
 48     inline int query(int x)
 49     {
 50         return n-(upper_bound(a+1,a+n+1,x)-a)+1;
 51     }
 52 }s[10000];
 53 int n,m,ans,size,cnt,top[maxn],tot[2],head[2][maxn],a[maxn],fa[maxn],b[maxn];
 54 struct edge{int go,next;}e[2][2*maxn];
 55 inline void add(int k,int x,int y)
 56 {
 57     e[k][++tot[k]]=(edge){y,head[k][x]};head[k][x]=tot[k];
 58 }
 59 inline void dfs(int x)
 60 {
 61     for4(i,0,x)if(y!=fa[x])
 62     {
 63         fa[y]=x;
 64         if(s[b[x]].n<size)s[b[y]=b[x]].insert(a[y]);
 65         else top[b[y]=++cnt]=y,s[cnt].insert(a[y]),add(1,b[x],b[y]);
 66         dfs(y);
 67     }
 68 }
 69 inline void query2(int x,int w)
 70 {
 71     ans+=s[x].query(w);
 72     for4(i,1,x)query2(y,w);
 73 }
 74 inline void query1(int x,int w)
 75 {
 76     if(a[x]>w)ans++;
 77     for4(i,0,x)if(y!=fa[x]){if(top[b[y]]==y)query2(b[y],w);else query1(y,w);}
 78 }
 79 int main()
 80 {
 81     freopen("input.txt","r",stdin);
 82     freopen("output.txt","w",stdout);
 83     n=read();
 84     for1(i,n-1){int x=read(),y=read();add(0,x,y);add(0,y,x);}
 85     for1(i,n)a[i]=read();
 86     s[b[1]=top[1]=cnt=1].insert(a[1]);
 87     size=sqrt(2*n*log2(n));
 88     dfs(1);
 89     m=read();
 90     while(m--)
 91     {
 92         int op=read(),x=read()^ans,y=read()^ans;
 93         if(op==0)
 94         {
 95             ans=0;
 96             if(top[b[x]]!=x)query1(x,y);
 97             else query2(b[x],y);
 98             printf("%d\n",ans);
 99         }else if(op==1)
100         {
101             s[b[x]].modify(a[x],y);
102             a[x]=y;
103         }else
104         {
105             a[++n]=y;add(0,x,n);fa[n]=x;
106             if(s[b[x]].n<size)s[b[n]=b[x]].insert(a[n]);
107             else top[b[n]=++cnt]=n,s[cnt].insert(a[n]),add(1,b[x],b[n]);
108         }
109     }
110     return 0;
111 }
View Code

 

posted @ 2015-01-25 19:43  ZYF-ZYF  Views(276)  Comments(0Edit  收藏  举报