某模拟赛C题 树上路径统计 (点分治)
题意
给定一棵有n个节点的无根树,树上的每个点有一个非负整数点权。定义一条路径的价值为路径上的点权和-路径上的点权最大值。 给定参数P,我!=们想知道,有多少不同的树上简单路径,满足它的价值恰好是P的倍数。 注意:单点算作一条路径;u!=v时,(u,v)和(v,u)只算一次。
题解
树上路径统计,解法是点分治。点分的时候求出根到每个点路径最大值和权值和。排一序,然后开个桶,就能计算了。去重就套路的减去没棵子树里面的答案。
CODE
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
typedef long long LL;
LL ans;
int n, mod, fir[MAXN], nxt[MAXN<<1], to[MAXN<<1], cnt, val[MAXN];
inline void link(int x, int y) {
	to[++cnt] = y; nxt[cnt] = fir[x]; fir[x] = cnt;
	to[++cnt] = x; nxt[cnt] = fir[y]; fir[y] = cnt;
}
bool ban[MAXN];
int getsz(int u, int ff) {
	int re = 1;
	for(int v, i = fir[u]; i; i = nxt[i])
		if((v=to[i]) != ff && !ban[v])
			re += getsz(v, u);
	return re;
}
int getrt(int u, int ff, int &rt, int Size) {
	int re = 1; bool can = 1;
	for(int v, tmp, i = fir[u]; i; i = nxt[i])
		if((v=to[i]) != ff && !ban[v]) {
			re += (tmp = getrt(v, u, rt, Size));
			if((tmp<<1) > Size) can = 0;
		}
	if(((Size-re)<<1) > Size) can = 0;
	if(can) rt = u;
	return re;
}
struct node {
	int mx, v;
	inline bool operator <(const node &o)const {
		return mx < o.mx;
	}
}seq[MAXN], vv[MAXN];
int tot;
void dfs(int u, int ff, int mx, int vs) {
	vs = (vs + val[u]) % mod;
	mx = max(mx, val[u]);
	vv[u] = (node){ mx, vs };
	for(int v, i = fir[u]; i; i = nxt[i])
		if((v=to[i]) != ff && !ban[v])
			dfs(v, u, mx, vs);
}
void push(int u, int ff) {
	seq[++tot] = vv[u];
	for(int v, i = fir[u]; i; i = nxt[i])
		if((v=to[i]) != ff && !ban[v])
			push(v, u);
}
int bin[10000005];
LL calc(int rt, int o) {
	tot = 0; push(rt, 0);
	sort(seq + 1, seq + tot + 1);
	LL re = 0;
	for(int i = 1; i <= tot; ++i) {
		re += bin[((seq[i].mx+o-seq[i].v)%mod+mod)%mod];
		++bin[seq[i].v%mod];
	}
	for(int i = 1; i <= tot; ++i) --bin[seq[i].v%mod];
	return re;
}
void solve(int x) {
	dfs(x, 0, 0, 0);
	ans += calc(x, val[x]);
	ban[x] = 1;
	for(int v, i = fir[x]; i; i = nxt[i])
		if(!ban[v=to[i]]) ans -= calc(v, val[x]);
}
void TDC(int x) {
	int Size = getsz(x, 0);
	getrt(x, 0, x, Size);
	solve(x);
	for(int v, i = fir[x]; i; i = nxt[i])
		if(!ban[v=to[i]]) TDC(v);
}
int main () {
	scanf("%d%d", &n, &mod);
	for(int i = 1, x, y; i < n; ++i)
		scanf("%d%d", &x, &y), link(x, y);
	for(int i = 1; i <= n; ++i) scanf("%d", &val[i]);
	TDC(1);
	printf("%lld\n", ans+n);
}
												
											某模拟赛C题 树上路径统计 (点分治)的更多相关文章
- 【2019.8.6 慈溪模拟赛 T2】树上路径(tree)(Trie)
		
从暴力考虑转化题意 考虑最暴力的做法,我们枚举路径的两端,然后采用类似求树上路径长度的做法,计算两点到根的贡献,然后除去\(LCA\)到根的贡献两次. 即,设\(v_i\)为\(i\)到根路径上的边权 ...
 - 【JZOJ4715】【NOIP2016提高A组模拟8.19】树上路径
		
题目描述 给出一棵树,求出最小的k,使得,且在树中存在路径p,使得k>=S且k<=E.(k为路径p上的边的权值和) 输入 第一行给出N,S,E.N代表树的点数,S,E如题目描述. 下面N- ...
 - 6.28 NOI模拟赛 好题 状压dp 随机化
		
算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...
 - 【csp模拟赛6】树上统计-启发式合并,线段树合并
		
30%:暴力 40%:枚举L,R从L~n枚举,R每增大一个,更新需要的边(bfs实现)60%:枚举每条边, 计算每条边的贡献另外20%的数据:枚举每条边,计算每条边的贡献100%:对于每一条边统计 有 ...
 - newcoder  NOIP提高组模拟赛C题——保护
		
我是发了疯才来写这道题的 我如果用写这道题的时间去写dp,我估计我能写上三四道 可怕的数据结构题 题目 这道题的鬼畜之处在于实在是不太好写 我们看到要求离树根尽量的近,所以我们很容易就能想到树上倍增, ...
 - 2016 10 26考试 NOIP模拟赛 杂题
		
Time 7:50 AM -> 11:15 AM 感觉今天考完后,我的内心是崩溃的 试题 考试包 T1: 首先看起来是个贪心,然而,然而,看到那个100%数据为n <= 2000整个人就虚 ...
 - 【2019.10.7 CCF-CSP-2019模拟赛 T1】树上查询(tree)(思维)
		
思维 这道题应该算是一道思维题吧. 首先你要想到,既然这是一棵无根树,就要明智地选择根--以第一个黑点为根(不要像我一样习惯性以\(1\)号点为根,结果直到心态爆炸都没做出来). 想到这一点,这题就很 ...
 - 6.29 省选模拟赛 坏题 AC自动机 dp 图论
		
考场上随手构造了一组数据把自己卡掉了 然后一直都是掉线状态了. 最后发现这个东西不是subtask -1的情况不多 所以就没管无解直接莽 写题有点晚 故没调出来.. 考虑怎么做 容易想到建立AC自动机 ...
 - 9 16 模拟赛&关于线段树上二分总结
		
1 考试时又犯了一个致命的错误,没有去思考T2的正解而是去简单的推了一下式子开始了漫漫找规律之路,不应该这样做的 为了得到规律虽然也打了暴力 但是还是打了一些不必要的程序 例如求组合数什么的比较浪费时 ...
 
随机推荐
- NetCore 开发时中文编码转换出现异常
			
在C#编程的时候难免会遇到需要转换编码的场合. 在Framwork中可以用System.Text.Encoding解决,但是到了core会发现,虽然也有这个东西,但几个关键的中文编码(比如GB2312 ...
 - 如何解决aws解绑银行卡问题?
			
首先先来说明一下我自己的情况? 一年的免费使用 前提:没有开启任何的实例服务 先贴一条官方的解释 关于我小白一个.学校课程要求使用aws,注册之后在网络上看到一堆人踩坑,aws的扣费就是个坑! 预授权 ...
 - vue组件、自定义指令、路由
			
1.vue组件 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的 ...
 - SpringBoot整合PageHelper做多条件分页查询
			
https://yq.aliyun.com/articles/619586 本篇博客讲述如何在SpringBoot中整合PageHelper,如何实现带多个条件,以及PageInfo中的属性的中文解释 ...
 - Linq 用得太随意导致的性能问题一则
			
问题场景 有一个很多条数据的数据库(数据源),在其中找出指定的项,这些项的 ID 位于 给定的列表中,如 TargetList 中. private readonly IDictionary<s ...
 - Python实现抽样分布的验证(正态分布、卡方分布、T分布)
			
参考链接:https://github.com/v-gazh/LearningStatsGroup/blob/master/week7/week7.ipynb 源地址:https://github.c ...
 - Python基础10
			
字符串大小写转换,除了upper,lower,还有一种方法,casefold( ) 方法 比较这两种方法的适用范围
 - iOS开发工具:Alcatraz、SVGKit、Lin以及Transformifier等
			
转自:http://www.cocoachina.com/applenews/devnews/2013/0606/6352.html Alcatraz:Xcode包管理器 Alcatraz是一个开源的 ...
 - Class.forName() 与 ClassLoader.loadClass()的区别
			
看到一个面试题,说说Class.forName() 与 ClassLoader.loadClass()的区别,特意记录一下,方便后续查阅. 在我们写java代码时,通常用这两种方式来动 ...
 - Python3报错:ModuleNotFoundError: No module named '_bz2'
			
系统信息 系统:CentOS Linux release 7.6.1810 (Core) python版本:python3.7 报错信息 from _bz2 import BZ2Compresso ...