写了一整天,怎么调也是T,不知道题解是怎么过去的。
具体的题解感觉跟我写的也差不多我就是T,可能有点卡常,还是我哪里姿势不对。
(难道是T在了链式前向星图上???)
下面代码是T了的,主要学习一下树分块的思想吧。
树分块主要就是在树上找一下关键点。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#define ll long long
#define llu unsigned ll
#define pr make_pair
#define pb push_back
//#define lc (cnt<<1)
//#define rc (cnt<<1|1)
using namespace std;
char buffer[100001],*S,*T;
inline char Get_Char()
{
if (S==T)
{
T=(S=buffer)+fread(buffer,1,100001,stdin);
if (S==T) return EOF;
}
return *S++;
}
inline int read()
{
char c;int re=0;
for(c=Get_Char();c<'0'||c>'9';c=Get_Char());
while(c>='0'&&c<='9') re=re*10+(c-'0'),c=Get_Char();
return re;
}
const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e15;
const int mod=1e9+7;
const int maxn=40002;
const int s=1000;
int head[maxn],ver[maxn<<1],nt[maxn<<1];
int d[maxn],f[maxn],son[maxn],si[maxn];
int id[maxn],top[maxn];
int tot=1,cnt=0,tp=0,cnts=0;
int val[maxn],a[maxn],st[maxn],sid[maxn],maxd[maxn],sf[maxn];
bitset<maxn>b[maxn/s+2][maxn/s+2],nowb;
void add(int x,int y)
{
ver[++tot]=y,nt[tot]=head[x],head[x]=tot;
}
void dfs1(int x,int fa)
{
int max_son=0;
si[x]=1;
maxd[x]=d[x];
for(int i=head[x];i;i=nt[i])
{
int y=ver[i];
if(y==fa) continue;
d[y]=d[x]+1;
f[y]=x;
dfs1(y,x);
si[x]+=si[y];
maxd[x]=max(maxd[x],maxd[y]);
if(si[y]>max_son) max_son=si[y],son[x]=y;
}
if(maxd[x]-d[x]>=s) sid[x]=++cnts,maxd[x]=d[x];
}
void dfs1p5(int x,int fa)
{
for(int i=head[x];i;i=nt[i])
{
int y=ver[i];
if(y==fa) continue;
if(sid[y])
{
int l=sid[st[tp]],r=sid[y];
for(int now=y;now!=st[tp];now=f[now])
b[l][r].set(val[now]);
nowb=b[l][r];
for(int j=1;j<tp;j)
b[sid[st[j]]][r]=b[sid[st[j]]][l]|nowb;
sf[y]=st[tp];
st[++tp]=y;
}
dfs1p5(y,x);
if(sid[y]) tp--;
}
}
void dfs2(int x,int t)
{
top[x]=t;
id[x]=++cnt;
if(!son[x]) return ;
dfs2(son[x],t);
for(int i=head[x];i;i=nt[i])
{
int y=ver[i];
if(y!=son[x]&&y!=f[x])
dfs2(y,y);
}
}
int lca(int x,int y)
{
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]]) swap(x,y);
x=f[top[x]];
}
return id[x]>id[y]?y:x;
}
int main(void)
{
int n,m;
int x,y;
n=read(),m=read();
for(int i=1;i<=n;i++)
{
val[i]=read();
a[i]=val[i];
}
sort(a+1,a+n+1);
int nc=unique(a+1,a+n+1)-(a+1);
for(int i=1;i<=n;i++)
val[i]=lower_bound(a+1,a+nc+1,val[i])-a;
for(int i=1;i<n;i++)
{
x=read(),y=read();
add(x,y);
add(y,x);
}
d[1]=1;
dfs1(1,0);
if(sid[1]==0) sid[1]=++cnts;
st[++tp]=1;
dfs1p5(1,0);
dfs2(1,1);
int ans=0;
for(int i=1;i<=m;i++)
{
x=read(),y=read();
x^=ans;
nowb.reset();
int lc=lca(x,y);
while(x!=lc&&!sid[x]) nowb.set(val[x]),x=f[x];
while(y!=lc&&!sid[y]) nowb.set(val[y]),y=f[y];
if(x!=lc)
{
int pre=x;
while(d[sf[pre]]>=d[lc]) pre=sf[pre];
if(pre!=x) nowb|=b[sid[pre]][sid[x]];
while(pre!=lc) nowb.set(val[pre]),pre=f[pre];
}
if(y!=lc)
{
int pre=y;
while(d[sf[pre]]>=d[lc]) pre=sf[pre];
if(pre!=y) nowb|=b[sid[pre]][sid[y]];
while(pre!=lc) nowb.set(val[pre]),pre=f[pre];
}
nowb.set(val[lc]);
printf("%d\n",ans=nowb.count());
}
return 0;
}