Codeforces - 570D discrete DFS order special subtree statistics (violent miracles)

The meaning of the question: Given a tree, each node on the tree has a corresponding character, ask multiple times whether any combination of characters on all nodes with a depth of \(d\) in the \(u\) subtree can make up a palindrome

Store the dfs order in a two-dimensional linear table, one dimension records the character and the other dimension records the depth.
Because the dfs order is monotonically increasing, the value of each two-dimensional table is also monotonically increasing,
so it is only necessary to use two binary divisions. my son can do it

It feels like a rather strange gesture, but I learned it anyway
//Is it really a man to be so violent in time and space?

#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define print(a) printf("%lld",(ll)(a))
#define println(a) printf("%lld\n",(ll)(a))
#define printbk(a) printf("%lld ",(ll)(a))
using namespace std;
const int MAXN = 5e5+11;
typedef long long ll;
ll read(){
    ll x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int to[MAXN<<1],nxt[MAXN<<1],head[MAXN],tot;
int CLOCK,st[MAXN],ed[MAXN],n,m;
char str[MAXN];
vector<int> save[MAXN][27];
void init(){
    memset(head,-1,sizeof head);
    tot=CLOCK=0;
}
void add(int u,int v){
    to[tot]=v;
    nxt[tot]=head[u];
    head[u]=tot++;
    swap(u,v);
    to[tot]=v;
    nxt[tot]=head[u];
    head[u]=tot++;
}
void dfs(int u,int p,int d){
    st[u]=++CLOCK;
    save[d][str[u]-'a'].push_back(st[u]);
    erep(i,u){
        int v=to[i];
        if(v==p)continue;
        dfs(v,u,d+1);
    }
    ed[u]=CLOCK;
}
int main(){
    while(cin>>n>>m){
        init();
        rep(i,2,n) add(i,read());
        scanf("%s",str+1);
        memset(save,0,sizeof save);
        dfs(1,-1,1);
        rep(i,1,m){
            int u=read();
            int d=read();
            bool flag=0,fflag=0;
            rep(j,0,25){
                vector<int>::iterator it1=lower_bound(save[d][j].begin(),save[d][j].end(),st[u]);
                vector<int>::iterator it2=upper_bound(save[d][j].begin(),save[d][j].end(),ed[u]);
                int cha=it2-it1;
                if((cha&1)&&!flag) flag=1;
                else if((cha&1)&&flag){
                    fflag=1;break;
                }
            }
            if(fflag) printf("No\n");
            else printf("Yes\n");
        }
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325211937&siteId=291194637