首页 > 其他 > 详细

1513 树上的回文

时间:2021-02-15 10:29:06      阅读:13      评论:0      收藏:0      [点我收藏+]

这题好妙啊,看讨论区很多做法,但我都不会^ ^

http://www.51nod.com/Question/Index.html#questionId=1542&isAsc=false

讨论区kczno1大佬的做法:

dfs一遍,每个深度记每个字母的奇偶性,这个用一个二进制数就可以了。
然后对每个询问 用该层进入子树前的数^退出子树时的数,判断它是否全0或者只有一个1 就好了。
 

 

/*input
6 5
1 1 1 3 3
zacccd
1 1
3 3
4 1
6 1
1 2
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

inline ll read() {
    char c = getchar(); ll x = 0, f = 1;
    while(c < 0 || c > 9) {if(c == -) f = -1; c = getchar();}
    while(c >= 0 && c <= 9) x = x * 10 + c - 0, c = getchar();
    return x * f;
}

const int inf=0x3f3f3f3f;
const int maxn=5e5+50;

int n, m;
int cnt, max_h;
char s[maxn];
int high[maxn];
vector<int> G[maxn], A[maxn], B[maxn];
pair<int, int> dfn[maxn];//in out

void dfs(int u, int fa, int h){
    max_h = max(h, max_h);
    high[u] = h;
    dfn[u].first = ++cnt;
    A[h].push_back(1<<(s[u] - a));
    B[h].push_back(cnt);

    for (auto v:G[u]) dfs(v, u, h + 1);

    dfn[u].second = cnt;
}

int solve(int x, int h){
    if (h <= high[x] || !B[h].size()) return 1;

    int l = (int)(lower_bound(B[h].begin(), B[h].end(), dfn[x].first) - B[h].begin());
    int r = (int)(upper_bound(B[h].begin(), B[h].end(), dfn[x].second) - B[h].begin() - 1);
    if (l > r)  return 1;

    int ans = A[h][r] ^ (l ? A[h][l - 1] : 0);
    if (ans == (ans & (-ans)))  return 1;//只能有1个1
    return 0;
}

int main(){
    n=read(), m=read();
    for (int i = 2,x; i <= n; i++){
        x=read();
        G[x].push_back(i);
    }

    scanf("%s", s+1);
    dfs(1,0,1);

    for (int i = 0; i <=max_h; i++)
        for (int j = 1; j < A[i].size(); j++)
            A[i][j] ^= A[i][j - 1];

    int v, h;
    while (m--) {
        v=read(), h=read();
        if (solve(v, h)) puts("Yes");
        else puts("No");
    }
    return 0;
}

 

1513 树上的回文

原文:https://www.cnblogs.com/noobimp/p/14402126.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!