首页 > 其他分享 >Codeforces Round #316 (Div. 2) D Tree Requests

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

时间:2022-09-19 00:44:59浏览次数:125  
标签:hson int siz Tree 316 Codeforces maxn nex now

Tree Requests

判断 \(V_i\) 的子树中,深度为 \(h_i\) 的结点上所带有的字符,能否组成一个回文串

启发式合并

维护所有深度上不同字符的数量,并且维护其奇数字符出现的次数

如果若干个字符能组成一个回文串,必然有:

  • 偶数个字符,且不出现奇数次数的字符

  • 奇数个字符,只能出现一个奇数次数的字符

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
#define pii pair<int, int>
typedef long long ll;
const int maxn = 1e5 + 10;
vector<int>gra[maxn];
int col[maxn], cnt[maxn], fa[maxn];
int siz[maxn], hson[maxn], ans[maxn];
int L[maxn], R[maxn], tp = 0, rnk[maxn];
int sum[maxn];
vector<pii>qs[maxn];

void dfs1(int now, int pre)
{
    L[now] = ++tp;
    fa[now] = pre;
    siz[now] = 1;
    hson[now] = -1;
    rnk[tp] = now;
    for(int nex : gra[now])
    {
        if(nex == pre) continue;
        dfs1(nex, now);
        siz[now] += siz[nex];
        if(hson[now] == -1 || siz[nex] > siz[hson[now]])
            hson[now] = nex;
    }
    R[now] = tp;
}

inline void add(int now)
{
    cnt[col[now]]++;
    sum[cnt[col[now]]]++;
}

inline void del(int now)
{
    sum[cnt[col[now]]]--;
    cnt[col[now]]--;
}

void dfs2(int now, bool keep)
{
    for(int nex : gra[now])
        if(nex != fa[now] && nex != hson[now]) dfs2(nex, false);
    if(hson[now] != -1) dfs2(hson[now], true);
    for(int nex : gra[now])
    {
        if(nex == fa[now] || nex == hson[now]) continue;
        for(int i=L[nex]; i<=R[nex]; i++)
            add(rnk[i]);
    }
    add(now);
    for(auto [k, id] : qs[now])
        ans[id] = sum[k];
    if(!keep)
    {
        for(int i=L[now]; i<=R[now]; i++)
            del(rnk[i]);
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    for(int i=1; i<=n; i++) cin >> col[i];
    for(int i=1; i<n; i++)
    {
        int a, b;
        cin >> a >> b;
        gra[a].push_back(b);
        gra[b].push_back(a);
    }
    for(int i=0; i<m; i++)
    {
        int a, b;
        cin >> a >> b;
        qs[a].push_back({b, i});
    }
    dfs1(1, 1);
    dfs2(1, true);
    for(int i=0; i<m; i++)
        cout << ans[i] << "\n";
    return 0;
}

标签:hson,int,siz,Tree,316,Codeforces,maxn,nex,now
From: https://www.cnblogs.com/dgsvygd/p/16706389.html

相关文章

  • Codeforces Round #221 (Div. 1) D Tree and Queries
    TreeandQueries询问\(V_j\)的子树中,有多少种颜色出现了\(K_j\)次启发式合并最直接的,树上启发式合并的同时维护颜色出现的次数,然后再拿一个数组记录一下出现了\(i......
  • Codeforces Round #151 (Div. 2) E Blood Cousins Return
    BloodCousinsReturn启发式合并在跑启发式合并的同时,对每个深度都维护一个\(set\),就可以自动去重并计算有多少种不同的字符串#include<iostream>#include<cstdio>......
  • 【题解】CF1311E Construct the Binary Tree
    题目链接-->Problem-E-Codeforces题目大意给定\(n\)和\(d\),你需要构造一棵\(n\)个点的二叉树满足所有点的深度之和恰好为\(d\)。\(2≤n,d≤5000\)。分析......
  • AtCoder Regular Contest 148 C Lights Out on Tree
    挺好的一道题,简单写一下题解吧。首先有挺多很naive的结论:每个节点按两遍等于没按。熄灭所有的灯只有一种方案。其实将灯熄灭的方案无非就是从上往下dfs,如果当前灯......
  • Codeforces Round #816 (Div. 2) A-D
    CodeforcesRound#816(Div.2)A-D传送门A题意:长为n,m的一个棋盘,左上的旗子要去右下,左下的棋子要去右上,每次移动花费为1,但当一个棋子在另一个棋子的轨迹上时,可以花费......
  • Codeforces Round #819 (Div. 1 + Div. 2) A-D
    CodeforcesRound#819(Div.1+Div.2)A-D传送门过程本场A小磕一下,浪费了一点时间,随后B的迷惑题面浪费大量时间,心态发生了变化,不过最后还是在强猜后蒙过了,C又浪费了......
  • Codeforces Round #819 (Div. 1 + Div. 2) 补题 C
    C.Jatayu'sBalancedBracketSequence(思维题)题意:给你一个平衡括号序列(符合书写规则),其任意子区间[i,j]如果是平衡子序列,就建立一条i,j之间的无权无向边,求最后建成的图......
  • Codeforces Round #819 (Div. 1 + Div. 2)
    \(\texttt{Unrated}\)好像是印度老哥又一次放了F原题,悲。A考虑保留头尾的数,\(3\)种情况的分讨,即保留\(a_1\),保留\(a_n\),或者都保留。MyCode#include<bits/stdc+......
  • Codeforces Round #816 (Div. 2)
    Preface早上7:20起来早自习,结果不知道背什么遂刷了好久知乎……下午只有一个思修课,一边划水一遍写题,堪堪做了ABCD晚上据说有C语言的程序设计?又可以摸鱼了好耶A.Crossm......
  • Educational Codeforces Round 40 (Rated for Div. 2) 补题
    E.WaterTaps题意:每个水龙头有一个流量限制\(a_i\),温度\(t_i\),现在让你控制每个水龙头的出水量\(x_i\),使得最终的水温为\(T\),水温的公式为$\frac{\sum\limits_{i=1}^{......