BZOJ 3720 树分块

借鉴了别人的代码……

//By SiriusRen
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 66666
struct Blocks{
    int a[210],size;
    void Insert(int x){
        ++size;int i;
        for(i=size;i>1&&a[i-1]>x;i--)a[i]=a[i-1];
        a[i]=x;
    }
    void Modify(int x,int y){
        int temp=lower_bound(a+1,a+1+size,x)-a;
        for(;temp<size&&a[temp+1]<y;temp++)a[temp]=a[temp+1];
        for(;temp>1&&a[temp-1]>y;temp--)a[temp]=a[temp-1];
        a[temp]=y; 
    }
    int Query(int x){
        return size-(upper_bound(a+1,a+1+size,x)-a)+1;
    }
}blocks[10500];
int n,m,op,xx,yy,block,cnt,ans,a[N],fa[N],belong[N];
int first[N],bfirst[N],next[N*2],v[N*2],tot;
void add(int Head[],int x,int y){v[tot]=y,next[tot]=Head[x],Head[x]=tot++;}
void DFS(int x){
    if(blocks[belong[fa[x]]].size==block)
        blocks[belong[x]=++cnt].Insert(a[x]),add(bfirst,belong[fa[x]],cnt);
    else blocks[belong[x]=belong[fa[x]]].Insert(a[x]);
    for(int i=first[x];~i;i=next[i])
        if(v[i]!=fa[x])fa[v[i]]=x,DFS(v[i]);
}
void bdfs(int x,int y){
    ans+=blocks[x].Query(y);
    for(int i=bfirst[x];~i;i=next[i])bdfs(v[i],y);
}
void dfs(int x,int y){
    if(a[x]>y)ans++;
    for(int i=first[x];~i;i=next[i])
        if(v[i]!=fa[x]){
            if(belong[v[i]]==belong[x])dfs(v[i],y);
            else bdfs(belong[v[i]],y);
        }
}
int main(){
    memset(first,-1,sizeof(first)),memset(bfirst,-1,sizeof(bfirst));
    scanf("%d",&n);
    for(int i=1;i<n;i++)
        scanf("%d%d",&xx,&yy),add(first,xx,yy),add(first,yy,xx);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    block=int(sqrt(n)+0.5),DFS(1);
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&op,&xx,&yy),xx^=ans,yy^=ans;
        if(!op){ans=0;dfs(xx,yy);printf("%d\n",ans);}
        else if(op==1)blocks[belong[xx]].Modify(a[xx],yy),a[xx]=yy;
        else{
            a[++n]=yy,add(first,xx,n),fa[n]=xx;
            if(blocks[belong[xx]].size==block)
                blocks[belong[n]=++cnt].Insert(a[n]),add(bfirst,belong[xx],cnt);
            else blocks[belong[n]=belong[xx]].Insert(a[n]);
        }
    }
}
posted @ 2017-02-26 13:59  SiriusRen  阅读(137)  评论(0编辑  收藏  举报