zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    用Metasploit破解Mysql用户名和密码
    利用Android的UXSS漏洞完成一次XSS攻击
    Kali linux渗透测试常用工具汇总2-渗透攻击
    Kali linux渗透测试常用工具汇总1
    phantomjs模拟登录
    javascript中的面向对象
    javascript中的闭包
    Python的高级特性11:拓展基本数据类型(dict)
    Python的高级特性10:无聊的@property
    Python的高级特性9:蹩脚的多态
  • 原文地址:https://www.cnblogs.com/Mychael/p/11991209.html
Copyright © 2011-2022 走看看