继树剖之后,lca可以用树剖球了!。
题目询问树内两个点之间的信息,我们想到两个点连成的链可以通过以1为根的链到x的值+y的值减去2*lca(x,y).维护一个26的数组存一下a-z,然后计算即可
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
typedef long long ll;
using namespace std;
#define rep(i,j,n) for(ll i=j;i<=n;i++)
#define per(i,j,n) for(ll i=j;i>=n;i--)
typedef unsigned long long ull;
typedef unsigned short us;
const ll INF= 1e18+7;
const ll maxx = 2e5+700;
ll mod;
const double eps=1e-8;
inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m;
ll fa[maxx],deep[maxx],size[maxx],son[maxx];
struct stu
{
ll to,next;
}A[maxx*2];
ll head[maxx],cnt=0;
ll top[maxx],id[maxx],a[maxx];
char ch[maxx];
ll num=0;
ll sum[maxx][28];
ll zhi[30];
void add(ll u,ll v)
{
A[cnt].to=v;
A[cnt].next=head[u];
head[u]=cnt++;
}
void dfs1(ll now,ll f)
{
ll k=0;
fa[now]=f;size[now]=1;
deep[now]=deep[f]+1;
sum[now][(ll)(ch[now]-'a'+1) ]++;
if(now!=1)
{
rep(i,1,26)
sum[now][i]+=sum[f][i];
}
for(ll i=head[now];~i;i=A[i].next)
{
if(A[i].to!=f)
{
dfs1(A[i].to,now);
size[now]+=size[A[i].to];
if(size[A[i].to]>k)
{
k=size[A[i].to];
son[now]=A[i].to;
}
}
}
}
void dfs2(ll now,ll f)
{
top[now]=f;
id[now]=++num;
if(son[now]==0) return ;
dfs2(son[now],f);
for(ll i=head[now];~i;i=A[i].next)
{
if(A[i].to!=fa[now]&&A[i].to!=son[now])
{
dfs2(A[i].to,A[i].to);
}
}
}
ll lca(ll x,ll y)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<=deep[top[y]] ) swap(x,y);
x=fa[x];
}
if(deep[x]<deep[y])
return x;
else return y;
}
int main()
{
ll t;
ll r;
rep(i,1,maxx-1) head[i]=-1;
cin>>n;
rep(i,1,n-1)
{
ll x,y;
scanf("%lld%lld",&x,&y);
add(x,y);
add(y,x);
}
scanf("%s",ch+1);
dfs1(1,0);
dfs2(1,1);
cin>>m;
rep(i,1,m)
{
ll x,y;
scanf("%lld%lld",&x,&y);
ll lc=lca(x,y);
ll f=0;
ll ans=0;
rep(j,1,26) zhi[j]=0;
zhi[(ll)(ch[lc]-'a'+1)]++;
rep(j,1,26)
{
zhi[j]+=sum[x][j];
zhi[j]+=sum[y][j];
zhi[j]-=2*sum[lc][j];
if(zhi[j]%2==1){
ans+=(zhi[j]-1);
f=1;
}
else ans+=zhi[j];
}
printf("%lld\n",ans+f);
}
return 0;
}