题解 P10536 [Opoi 2024] 二十六点
与字符集大小无关的 场上写的是时空
若字符集较大可以先离散化,下面认为字符集大小为
用线段树合并维护第二维,可以
求答案时,设
枚举子序列的第一个点,有
对于互为父子的点
设
注意到 我不会)的求
因此只需判断是否有
即可求出
开
总时空复杂度均为
#include<bits/stdc++.h>
namespace IO{
const int L=(1<<20)+30;
char buf[L],*s,*t,pbuf[L],*p=pbuf;
#define gf() (s==t&&(s=buf)==(t=buf+fread(buf,1,L,stdin))?-1:*s++)
void rd(int&x){
x=0;char c=gf();
while(c<48) c=gf();
while(c>=48) x=x*10+(c^48),c=gf();
}
void rd(char*x){
do *x=gf();while(*x<48);
while(*x>=48) *x-='a'-1,*++x=gf();
*x=0;
}
void fl(){fwrite(pbuf,1,p-pbuf,stdout),p=pbuf;}
void pf(char c){if(p-pbuf==L) fl();*p++=c;}
void wt(int x){
static int st[30],tp;
do st[++tp]=x%10,x/=10;while(x);
while(tp) pf(st[tp--]|48);
pf(10);
}
}
using IO::rd;
using IO::wt;
using namespace std;
const int N=100005;
int n,m=26,maxr,p[N],dep[N],ans[N],dfn[N],sz[N],tim,len[N],son[N],s[N],h[N],rt[N],idx;
struct tn{int Ls,Rs,v;}tr[N*18];
#define ls tr[u].Ls
#define rs tr[u].Rs
vector<int>E[N],F[N];
char c[N];
int query(int u,int L,int R,int l=1,int r=maxr){
if(!u||(L<=l&&r<=R)) return tr[u].v;
int mid=(l+r)/2,z=0;
if(L<=mid) z=query(ls,L,R,l,mid);
if(R>mid) z=max(z,query(rs,L,R,mid+1,r));
return z;
}
void insert(int&u,int x,int v,int l=1,int r=maxr){
if(!u) tr[u=++idx]={0,0,0};
if(tr[u].v=max(tr[u].v,v),l<r){
int mid=(l+r)/2;
x>mid?insert(rs,x,v,mid+1,r):insert(ls,x,v,l,mid);
}
}
int merge(int u,int v){
if(!u||!v) return u^v;
ls=merge(ls,tr[v].Ls),rs=merge(rs,tr[v].Rs);
return tr[u].v=max(tr[u].v,tr[v].v),u;
}
void getdep(int x,int pr){
sz[x]=1;
for(int y:E[x])
if(y^pr){
dep[y]=dep[x]+1,getdep(y,x),sz[x]+=sz[y];
if(len[y]>len[son[x]]) son[x]=y;
}
len[x]=son[x]?len[son[x]]:dep[x];
}
void dfs(int x,int pr){
dfn[x]=++tim;
if(son[x]) dfs(son[x],x),rt[x]=rt[son[x]];
for(int y:E[x])
if(y^pr&&y^son[x]){
dfs(y,x),rt[x]=merge(rt[x],rt[y]);
for(int i=dep[y];i<=len[y];++i)
s[dfn[x]+i-dep[y]+1]=max(s[dfn[x]+i-dep[y]+1],s[dfn[y]+i-dep[y]]);
}
h[x]=1+query(rt[x],c[x],m);
insert(rt[x],c[x],h[x]),s[dfn[x]]=tr[rt[x]].v;
ans[x]=len[x]<dep[x]+p[x]?1:s[dfn[x]+p[x]];
F[int(c[x])].emplace_back(x);
}
#define eb emplace_back
int main(){
rd(n);
for(int i=1;i<=n;++i) rd(p[i]);
rd(c+1);
for(int i=1,u,v;i<n;++i)
rd(u),rd(v),E[u].eb(v),E[v].eb(u);
getdep(1,1),maxr=m,dfs(1,1),idx=0,maxr=n;
for(int i=1;i<=n;++i) rt[i]=0;
for(int i=m;i;--i){
for(int x:F[i]) insert(rt[h[x]],dfn[x],dep[x]);
for(int x:F[i])
if(sz[x]>1)
ans[x]+=query(rt[ans[x]],dfn[x]+1,dfn[x]+sz[x]-1)>=dep[x]+p[x];
}
for(int i=1;i<=n;++i) wt(ans[i]);
return IO::fl(),0;
}