码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #316 (Div. 2) D Tree Requests

时间:2015-08-15 00:01:55      阅读:512      评论:0      收藏:0      [点我收藏+]

标签:

官方题解是离线询问,dfs树形转线性,然后二分找区间。

还有一种比较好的做法是直接dfs,将当前访问这个结点u相关的询问之前的状态存起来,然后访问完以后利用异或开关性,得到这颗子树上的答案。

代码是学习别人的http://blog.csdn.net/squee_spoon/article/details/47666667

当时做的时候想得是树形转线性,觉得dfs会暴栈,想用bfs,之前又没写过,于是愣了一个钟头。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5+5;

char s[maxn];

int head[maxn],to[maxn],nxt[maxn],ecnt;

void addEdge(int u,int v)
{
    to[ecnt] = v;
    nxt[ecnt] = head[u];
    head[u] = ecnt++;
}

int qhead[maxn],qnxt[maxn];

void init()
{
    memset(head,-1,sizeof(head));
    memset(qhead,-1,sizeof(qhead));
}

struct Query
{
    int h;
    int other;
    bool ans;
}query[maxn];

void addQuery(int v,int i)
{
    qnxt[i] = qhead[v];
    qhead[v] = i;
}


bool ok(int n)
{
    while(n){
        if(n&1){
            return !(n>>1);
        }
        n>>=1;
    }
    return true;
}
int d[maxn];
int cnt[maxn];
void dfs(int u)
{
    for(int i = qhead[u]; ~i; i = qnxt[i]){
        query[i].other = cnt[query[i].h];
    }
    cnt[d[u]] ^= (1<<(s[u]-a));
    for(int i = head[u]; ~i; i = nxt[i]){
        d[to[i]] = d[u]+1;
        dfs(to[i]);
    }
    for(int i = qhead[u]; ~i; i = qnxt[i]){
        query[i].ans = ok(cnt[query[i].h]^query[i].other);
    }
}

int main()
{
    init();
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 2; i <= n; i++){
        int fa; scanf("%d",&fa);
        addEdge(fa,i);
    }
    scanf("%s",s+1);
    for(int i = 0; i < m; i++){
        int v; scanf("%d%d",&v,&query[i].h);
        addQuery(v,i);
    }
    d[1] = 1;
    dfs(1);
    for(int i = 0; i < m; i++){
        query[i].ans?puts("Yes"):puts("No");
    }
    return 0;
}

 

Codeforces Round #316 (Div. 2) D Tree Requests

标签:

原文地址:http://www.cnblogs.com/jerryRey/p/4731532.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!