• codeforces570D Tree Requests


    题目链接:codeforces570D

    正解:$dsu$ $on$ $tree$

    解题报告:

      考虑这又是一类子树内的不带修改统计问题,直接上$dsu$ $on$ $tree$好咯。

      直接按上一道题的做法做,类似地存一下每个深度每种字符的出现次数,对于每个点的询问,在每个点处查询一下就好了,只需奇数的个数$<=1$即可。

    //It is made by ljh2000
    //有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #include <set>
    #include <string>
    #include <complex>
    #include <bitset>
    using namespace std;
    typedef long long LL;
    typedef long double LB;
    typedef complex<double> C;
    const double pi = acos(-1);
    const int MAXN = 500011;
    const int MAXM = 1000011;
    int n,m,ecnt,first[MAXN],to[MAXM],next[MAXM],Son,ans[MAXN];
    int size[MAXN],son[MAXN],deep[MAXN],cnt[MAXN][26];
    char ch[MAXN];
    struct node{ int x,id; }tmp;
    vector<node>w[MAXN];
    
    inline void link(int x,int y){ next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; }
    inline int getint(){
        int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
        if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    }
    
    inline void dfs(int x,int fa){
    	size[x]=1;
    	for(int i=first[x];i;i=next[i]) {
    		int v=to[i]; if(v==fa) continue;
    		deep[v]=deep[x]+1;
    		dfs(v,x); size[x]+=size[v];
    		if(size[v]>size[son[x]]) son[x]=v;
    	}
    }
    
    inline void add(int x,int fa,int val){
    	cnt[ deep[x] ][ ch[x]-'a' ]+=val;
    	for(int i=first[x];i;i=next[i]) {
    		int v=to[i]; if(v==fa || v==Son) continue;
    		add(v,x,val);
    	}
    }
    
    inline void solve(int x,int fa,bool top){
    	for(int i=first[x];i;i=next[i]) {
    		int v=to[i]; if(v==fa || v==son[x]) continue;
    		solve(v,x,1);
    	}
    	if(son[x])
    		solve(son[x],x,0),Son=son[x];
    
    	add(x,fa,1);
    	Son=0;
    
    	//处理在x上的询问
    	for(int i=0,ss=w[x].size();i<ss;i++) {
    		tmp=w[x][i]; if(tmp.x<deep[x]) { ans[tmp.id]=1; continue; }
    		int cc=0,h=tmp.x;
    		for(int j=0;j<26;j++) if(cnt[h][j]&1) cc++;
    		if(cc>1) ans[tmp.id]=0;
    		else ans[tmp.id]=1;
    	}
    
    	if(top)
    		add(x,fa,-1);
    }
    
    inline void work(){
    	n=getint(); m=getint();  int x,y;
    	for(int i=2;i<=n;i++) { x=getint(); link(x,i); }
    	scanf("%s",ch+1);
    	deep[1]=1; dfs(1,0);
    	for(int i=1;i<=m;i++) { x=getint(); y=getint(); tmp.x=y; tmp.id=i; w[x].push_back(tmp); }
    	solve(1,0,1);
    	for(int i=1;i<=m;i++)
    		if(ans[i]) puts("Yes");
    		else puts("No");
    }
    
    int main()
    {
        work();
        return 0;
    }
    //有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
    

      

  • 相关阅读:
    uva11922splay
    获取的二维数组排序
    二维数组排序
    $.extend
    <eq>标签
    datagrid时间插件
    id=%d是什么意思呢?
    获得某一月的第一天,最后一天
    数组合并
    phpexcel 导入导出excel表格
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6529123.html
Copyright © 2020-2023  润新知