打块状树的时候发现以前的板子是错的。。
心累
不管了 不填坑了。。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
char c;
inline void read(int&a)
{a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
int n;
int max(int a,int b){return a>b?a:b;}
int Data[100001];
struct Block
{
int A[1001];
int con;
inline void add(int D)
{
int i;
con++;
for(i=1;A[i]>D&&i<con;i++);
int j=i;
for(i=con-1;i>=j;i--)
A[i+1]=A[i];
A[j]=D;
}
inline void Del(int D)
{
int i;
for(i=1;A[i]>D&&i<con;i++);
for(i;i<con;i++)
A[i]=A[i+1];
con--;
}
inline void Cg(int x,int New)
{
Del(Data[x]);
add(Data[x]=New);
}
inline int Query(int D)
{
A[0]=1<<29;
A[con+1]=-A[0];
int l=0,mid,r=1+con;
while(l<r)
{
mid=l+r>>1;
mid++;
if(A[mid]<=D)r=mid-1;
else l=mid;
}
return l;
}
}L[1001];
int no;
int Belong[100001];
int size;
int Con;
int Stack[100001];
struct Chain
{
Chain *next;
int u;
}*Head[1000001],*H[100001];
inline void Add(int u,int v)
{
if(u==1704)
u++,u--;
Chain *tp=new Chain;
tp->u=v;
tp->next=Head[u];Head[u]=tp;
}
inline void AddH(int u,int v)
{
Chain *tp=new Chain;
tp->u=v;
tp->next=H[u];H[u]=tp;
}
inline bool cmp(int a,int b){return a>b;}
int fa[100001];
int s[100001];
int Cache[100001],t;
int top[100001];
void ReBuild(int x,int f)
{
fa[x]=f;
s[x]=0;
Stack[++Con]=x;
if(Con>100000)
x++,x--;
top[x]=Cache[t];
if(x==1704)
x++,x--;
for(Chain *tp=Head[x];tp;tp=tp->next)
if(tp->u^f)
{
ReBuild(tp->u,x);
if(s[tp->u]+s[x]>=size)
{
s[x]=0;
no++;
int Q=0;
while(Stack[Con]^x)
Belong[Stack[Con]]=no,L[no].A[++Q]=Data[Stack[Con]],Con--;
while(Cache[t]!=top[Stack[Con+1]])
AddH(Cache[t],no),AddH(no,Cache[t]),t--;
Cache[++t]=no;
L[no].con=Q;
sort(L[no].A+1,L[no].A+1+Q,cmp);
}
else s[x]+=s[tp->u];
}
s[x]++;
if(x==f)
{
s[x]=0;
no++;
int Q=0;
while(Con)
Belong[Stack[Con]]=no,L[no].A[++Q]=Data[Stack[Con]],Con--;
while(Cache[t]!=top[x])
AddH(Cache[t],no),AddH(no,Cache[t]),t--;
Cache[++t]=no;
L[no].con=Q;
sort(L[no].A+1,L[no].A+1+Q,cmp);
}
/*if(size<=Con)
{
no++;
for(int i=1;i<=Con;i++)
Belong[Stack[i]]=no,L[no].A[i]=Data[Stack[i]];
L[no].con=Con;
sort(L[no].A+1,L[no].A+Con+1,cmp);
Con=0;
}
if(x==f&&Con)
{
no++;
for(int i=1;i<=Con;i++)
Belong[Stack[i]]=no,L[no].A[i]=Data[Stack[i]];
L[no].con=Con;
sort(L[no].A+1,L[no].A+Con+1,cmp);
Con=0;
}*/
}
int Query_B(int u,int f,int x)
{
int res=L[u].Query(x);
for(Chain *tp=H[u];tp;tp=tp->next)
if(tp->u!=f)res+=Query_B(tp->u,u,x);
return res;
}
bool Vis[100001];
int Query(int u,int f,int x)
{
int res=0;
if(Data[u]>x)res++;
for(Chain*tp=Head[u];tp;tp=tp->next)
if(f^tp->u)
if(Belong[tp->u]^Belong[u])
if(!Vis[Belong[tp->u]])
res+=Query_B(Belong[tp->u],Belong[u],x),Vis[Belong[tp->u]]=true;
else;
else res+=Query(tp->u,u,x);
return res;
}
int main()
{
int n,m;
read(n);
int ans;
int u,v;
for(int i=2;i<=n;i++)
read(u),read(v),Add(u,v),Add(v,u);
for(int i=1;i<=n;i++)read(Data[i]);
no=0;
size=max(sqrt(n),1);
ReBuild(1,1);
ans=0;
read(m);
int O=0,q=sqrt(m);
int x;
while(m--)
{
int op;
read(op);
if(op==0)
{
memset(Vis,false,sizeof(Vis));
read(u),read(x);
u^=ans,x^=ans;
ans=Query(u,fa[u],x);
printf("%d\n",ans);
}
else if(op==1)
{
read(u),read(x);
x^=ans,u^=ans;
L[Belong[u]].Cg(u,x);
}
else
{
n++;
O++;
read(u),read(x);
u^=ans,x^=ans;
Data[n]=x;
Add(u,n),Add(n,u);
Belong[n]=Belong[u];
fa[n]=u;
L[Belong[n]].add(x);
if(O>q)
{
memset(H,0,sizeof(H));
O=0;
no=0;
Con=0;
t=0;
size=max(sqrt(n),1);
ReBuild(1,1);
}
}
}
return 0;
}