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");
                }
            }
        }
    }
  • 相关阅读:
    ubuntu安装jdk的两种方法
    LeetCode 606. Construct String from Binary Tree (建立一个二叉树的string)
    LeetCode 617. Merge Two Binary Tree (合并两个二叉树)
    LeetCode 476. Number Complement (数的补数)
    LeetCode 575. Distribute Candies (发糖果)
    LeetCode 461. Hamming Distance (汉明距离)
    LeetCode 405. Convert a Number to Hexadecimal (把一个数转化为16进制)
    LeetCode 594. Longest Harmonious Subsequence (最长的协调子序列)
    LeetCode 371. Sum of Two Integers (两数之和)
    LeetCode 342. Power of Four (4的次方)
  • 原文地址:https://www.cnblogs.com/ainixu1314/p/4732329.html
Copyright © 2011-2022 走看看