CF570D Tree Requests

题目链接

CF570D

题解

复习dsu on tree
就是基于树剖均摊O(nlogn)的暴力
这题维护每一层的各个字母数量的奇偶性就行了

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define cls(s,v) memset(s,v,sizeof(s))
#define mp(a,b) make_pair<int,int>(a,b)
#define cp pair<int,int>
#define ls (u << 1)
#define rs (u << 1 | 1)
using namespace std;
const int maxn = 500005,maxm = 1000005,INF = 0x3f3f3f3f;
inline int read(){
    int out = 0,flag = 1; char c = getchar();
    while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();}
    while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();}
    return flag ? out : -out;
}
char s[maxn];
int N,M,h[maxn],ne;
struct EDGE{
    int to,nxt;
}ed[maxm];
int q[maxn],qi;
struct Query{
    int id,h,nxt;
}Q[maxn];
void add(int u,int id,int H){
    Q[++qi] = (Query){id,H,q[u]}; q[u] = qi;
}
void build(int u,int v){
    ed[++ne] = (EDGE){v,h[u]}; h[u] = ne;
    ed[++ne] = (EDGE){u,h[v]}; h[v] = ne;
}

int fa[maxn],son[maxn],siz[maxn],dep[maxn],c[maxn];
void dfs1(int u){
    siz[u] = 1; dep[u] = dep[fa[u]] + 1;
    for (int k = h[u],to; k; k = ed[k].nxt)
        if ((to = ed[k].to) != fa[u]){
            fa[to] = u;
            dfs1(to);
            siz[u] += siz[to];
            if (!son[u] || siz[to] > siz[son[u]]) son[u] = to;
        }
}
int ans[maxn];
int sum[maxn][26],odd[maxn];
void upd(int u,int v){
    sum[dep[u]][c[u]] += v;
    if (sum[dep[u]][c[u]] & 1) odd[dep[u]]++;
    else odd[dep[u]]--;
}
void cal(int u,int v){
    upd(u,v);
    Redge(u) if ((to = ed[k].to) != fa[u]) cal(to,v);
}
void dfs(int u){
    Redge(u) if ((to = ed[k].to) != fa[u] && to != son[u]) dfs(to);
    if (son[u]) dfs(son[u]);
    upd(u,1);
    Redge(u) if ((to = ed[k].to) != fa[u] && to != son[u]) cal(to,1);
    for (int k = q[u]; k; k = Q[k].nxt)
        ans[Q[k].id] = (odd[Q[k].h] <= 1) ? true : false;
    if (son[fa[u]] != u) cal(u,-1);
}
int main(){
    N = read(); M = read();
    for (int i = 2; i <= N; i++) build(i,read());
    scanf("%s",s + 1);
    for (int i = 1; i <= N; i++) c[i] = s[i] - 'a';
    for (int i = 1; i <= M; i++){
        int u = read(),H = read();
        add(u,i,H);
    }
    dfs1(1);
    dfs(1);
    for (int i = 1; i <= M; i++) puts(ans[i] ? "Yes" : "No");
    return 0;
}

这里丢一个dsu on tree的板子

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define cls(s,v) memset(s,v,sizeof(s))
#define mp(a,b) make_pair<int,int>(a,b)
#define cp pair<int,int>
#define ls (u << 1)
#define rs (u << 1 | 1)
using namespace std;
const int maxn = 100005,maxm = 400005,INF = 0x3f3f3f3f;
inline int read(){
    int out = 0,flag = 1; char c = getchar();
    while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();}
    while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();}
    return flag ? out : -out;
}
int N,h[maxn],ne;
struct EDGE{
    int to,nxt;
}ed[maxm];
void build(int u,int v){
    ed[++ne] = (EDGE){v,h[u]}; h[u] = ne;
    ed[++ne] = (EDGE){u,h[v]}; h[v] = ne;
}
int fa[maxn],son[maxn],siz[maxn],c[maxn];
void dfs1(int u){
    siz[u] = 1;
    for (int k = h[u],to; k; k = ed[k].nxt)
        if ((to = ed[k].to) != fa[u]){
            fa[to] = u;
            dfs1(to);
            siz[u] += siz[to];
            if (!son[u] || siz[to] > siz[son[u]]) son[u] = to;
        }
}
LL ans[maxn],bac[maxn];
LL mx,Ans;
void upd(int u,int v){
    bac[c[u]] += v;
    if (v < 0) return;
    if (bac[c[u]] == mx) Ans += c[u];
    else if (bac[c[u]] > mx) mx = bac[c[u]],Ans = c[u];
}
void cal(int u,int v){
    upd(u,v);
    Redge(u) if ((to = ed[k].to) != fa[u]) cal(to,v);
}
void dfs(int u){
    Redge(u) if ((to = ed[k].to) != fa[u] && to != son[u]) dfs(to);
    if (son[u]) dfs(son[u]);
    upd(u,1);
    Redge(u) if ((to = ed[k].to) != fa[u] && to != son[u]) cal(to,1);
    ans[u] = Ans;
    if (son[fa[u]] != u) cal(u,-1),Ans = mx = 0;
}
int main(){
    N = read();
    REP(i,N) c[i] = read();
    for (int i = 1; i < N; i++) build(read(),read());
    dfs1(1);
    dfs(1);
    for (int i = 1; i <= N; i++) printf("%I64d ",ans[i]);
    return 0;
}
上一篇:c++ 引用的一个错


下一篇:设计模式:JDK中的简单工厂