zoukankan      html  css  js  c++  java
  • Codeforces Round #316 (Div. 2) D

    题意:给你一个一棵树,树上的每个节点上有一个字符,询问 v,deep, 问深度为deep的,并且属于v子树的所有字符能不能组成一个回文,是数Yes,否则No

     对于这颗树,我们可以用 时间戳 来表示点v所包含的区间

    然后对于每一层我们可以把这些字符存在一个数组里面

    所以要找到 属于V的字符,且在deep层

    我们可以对于这一层进行二分(因为在同义层的时间时递增的)

    #include<bits/stdc++.h>
    using namespace std;
    const int mmax = 5e5+10;
    int n,m;
    int depp[mmax],TT;
    char p[mmax];
    struct Node{
        int num[26];
    };
    vector<char>sum[mmax];
    vector<int>ID[mmax];
    vector<Node>ans[mmax];
    vector<int>tp[mmax];
    bool vit[mmax];
    struct node{
        int st,ed;
    }pp[mmax];
    void dfs(int x,int cnt){
        sum[cnt].push_back(p[x]);
        ID[cnt].push_back(x);
        TT++;vit[x]=1;
        pp[x].st=TT;
        for(int i=0;i<tp[x].size();i++){
            int to=tp[x][i];
            if(!vit[to]) dfs(to,cnt+1);
        }
        pp[x].ed=TT;
    }
    void init(){
        for(int i=0;i<=n;i++) {
            sum[i].clear();
            tp[i].clear();
            ID[i].clear();
            ans[i].clear();
        }
        memset(ans,0,sizeof(ans));
        memset(vit,0,sizeof(vit));
    }
    int lfind(int l,int r,int x,int b){
        int mid,ans=mmax;
        while(l<=r){
            mid=(l+r)>>1;
            int id=ID[b][mid];
            if(pp[id].st>=pp[x].st){
                ans=mid;r=mid-1;
            }
            else l=mid+1;
        }
        return ans;
    }
    int rfind(int l,int r,int x,int b){
        int mid,ans=-1;
        while(l<=r){
            mid=(l+r)>>1;
            int id=ID[b][mid];
            if(pp[id].ed<=pp[x].ed){
                ans=mid;l=mid+1;
            }
            else r=mid-1;
        }
        return ans;
    }
    int main(){
        #ifndef ONLINE_JUDGE
        freopen("input.txt","r",stdin);
        #endif // ONLINE_JUDGE
        while(cin>>n>>m){
            init();
            for(int i=2;i<=n;i++){
                int a;scanf("%d",&a);
                tp[a].push_back(i);
                tp[i].push_back(a);
            }
            TT=0;
            scanf("%s",p+1);
            dfs(1,1);
            for(int i=1;i<=n;i++){
                if(sum[i].size()==0) continue;
                 Node a;
                memset(a.num,0,sizeof(a.num));
                for(int j=0;j<sum[i].size();j++){
                    int id=sum[i][j]-'a';
                    a.num[id]++;
                    ans[i].push_back(a);
                }
            }
            for(int i=0;i<m;i++){
                int a,b;scanf("%d%d",&a,&b);
                int ll,rr;
                ll=lfind(0,ans[b].size()-1,a,b);
                rr=rfind(0,ans[b].size()-1,a,b);
                if(ll>rr) puts("Yes");
                else{
                    int tsum=0;
                    if(ll==0){
                        tsum=0;
                        for(int j=0;j<26;j++) if(ans[b][rr].num[j]&1) tsum++;
                    }
                    else{
                        Node a;
                        for(int j=0;j<26;j++)
                        a.num[j]=ans[b][rr].num[j]-ans[b][ll-1].num[j];
                        tsum=0;
                        for(int j=0;j<26;j++) if(a.num[j]&1) tsum++;
    
                    }
                    if(tsum>1) puts("No");
                    else puts("Yes");
                }
            }
        }
    }
  • 相关阅读:
    hdoj 6023 Automatic Judge
    hdoj 1170 Balloon Comes!
    初识vim操作和配置
    POJ 1611 The Suspects (并查集)
    HDU 1232 畅通工程 (并查集)
    计蒜客--两数之和
    计蒜客--爬楼梯 (动态规划)
    计蒜客--单独的数字 (位运算)
    计蒜客--最后一个单词的长度
    计蒜客-- 奇怪的国家 (位运算)
  • 原文地址:https://www.cnblogs.com/ainixu1314/p/4732329.html
Copyright © 2011-2022 走看看