【题目大意】

给一棵树,求有多少条路径满足总和-最大值 是P的倍数

n<=10^5, P<=10^7

【题解】

一看就是点分治嘛

不考虑子树合并,考虑poj1741的做法,每次考虑经过重心的路径,用优先队列,从小到达添加并求答案即可。

容斥下。

# include <queue>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h> using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = 1e5 + , M = 2e5 + , MAX = 1e7 + ;
const int mod = 1e9+; # define RG register
# define ST static int n, P, v[N];
int head[N], nxt[M], to[M], tot;
inline void add(int u, int v) {
++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
}
inline void adde(int u, int v) {
add(u, v), add(v, u);
} namespace DFZ {
bool vis[N];
int sz[N], mx[N];
inline void dfsSize(int x, int fa = ) {
sz[x] = , mx[x] = ;
for (int i=head[x]; i; i=nxt[i]) {
if(to[i] == fa || vis[to[i]]) continue;
dfsSize(to[i], x);
sz[x] += sz[to[i]];
if(sz[to[i]] > mx[x]) mx[x] = sz[to[i]];
}
}
int mi, centre;
inline void dfsCentre(int x, int tp, int fa = ) {
if(sz[tp] - sz[x] > mx[x]) mx[x] = sz[tp] - sz[x];
if(mx[x] < mi) mi = mx[x], centre = x;
for (int i=head[x]; i; i=nxt[i]) {
if(to[i] == fa || vis[to[i]]) continue;
dfsCentre(to[i], tp, x);
}
} struct pa {
int x, s, mx, fa;
pa() {}
pa(int x, int s, int mx, int fa) : x(x), s(s), mx(mx), fa(fa) {}
friend bool operator < (pa a, pa b) {
return a.mx > b.mx;
}
}; priority_queue<pa> q;
int buc[MAX];
int st[M], stn; inline void delAns(int x, int s, int fa) {
-- buc[s];
for (int i=head[x]; i; i=nxt[i]) {
if(to[i] == fa || vis[to[i]]) continue;
delAns(to[i], (s + v[to[i]]) % P, x);
}
} inline ll doit(int x, int temp_s, int temp_mx, int temp_fa, int Vx) {
ll ret = ; (temp_s += v[x]) %= P; temp_mx = max(temp_mx, v[x]);
while(!q.empty()) q.pop(); stn = ;
q.push(pa(x, temp_s, temp_mx, temp_fa));
while(!q.empty()) {
pa tp = q.top(); q.pop();
// tp.s + S - Vx - mx = 0 (mod P)
// S = Vx + mx - tp.s
ret += buc[((tp.mx + Vx - tp.s) % P + P) % P];
++ buc[tp.s];
st[++stn] = tp.s;
for (int i=head[tp.x]; i; i=nxt[i]) {
if(to[i] == tp.fa || vis[to[i]]) continue;
q.push(pa(to[i], (tp.s + v[to[i]]) % P, max(tp.mx, v[to[i]]), tp.x));
}
}
for (int i=stn; i; --i) -- buc[st[i]];
return ret;
} ll ans;
inline void dfs(int x) {
dfsSize(x); mi = n;
dfsCentre(x, x);
x = centre;
// ===== //
// printf("x = %d\n", x);
ans += doit(x, , , , v[x]);
// ===== //
vis[x] = ;
for (int i=head[x]; i; i=nxt[i])
if(!vis[to[i]]) {
ans -= doit(to[i], v[x], v[x], x, v[x]);
dfs(to[i]);
}
} inline void main() {
ans = ;
dfs();
ans += n;
cout << ans << endl;
}
} int main() {
freopen("c.in", "r", stdin);
freopen("c.out", "w", stdout);
cin >> n >> P;
for (int i=, u, tv; i<n; ++i) {
scanf("%d%d", &u, &tv);
adde(u, tv);
}
for (int i=; i<=n; ++i) scanf("%d", v+i);
DFZ::main();
return ;
}
/*
5 2
1 2
1 3
2 4
3 5
1 3 3 1 2
*/

校内训练0609 problem c的更多相关文章

  1. 「校内训练 2019-04-23」越野赛车问题 动态dp+树的直径

    题目传送门 http://192.168.21.187/problem/1236 http://47.100.137.146/problem/1236 题解 题目中要求的显然是那个状态下的直径嘛. 所 ...

  2. [4.14校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. hzwer又出丧题虐人 4道noi....        很奇怪 每次黄学长出题总有一题我做过了. 嗯题目你们自己看看呗 好难解释 ----- ...

  3. [2017.4.7校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 报警啦.......hzwer又出丧题虐人啦..... 4道ctsc...有一道前几天做过了,一道傻逼哈希还wa了十几次,勉强过了3题..我好 ...

  4. [3.24校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. ----------------------------------------------------------------------- ...

  5. 19_04_19校内训练[Game]

    题意 给出n,等概率地生成一个1~n的数列.现在有n个人从左到右站成一排,每个人拿有当前数列位置上的数字,并且一开始都不知道数字是多少(但知道n是多少).从左到右让每个人进行如下选择: 1.选择保留自 ...

  6. 19_04_02校内训练[deadline]

    题意 给出一个二分图,左边为A集合,右边为B集合,要求把A集合中每一个点染为黑白两色中的一种,B集合中的颜色已定.染色后对于原本相邻且颜色相同的点,建立新的二分图,即得到了两个新的二分图,它们是独立的 ...

  7. 平面图转对偶图&19_03_21校内训练 [Everfeel]

    对于每个平面图,都有唯一一个对偶图与之对应.若G‘是平面图G的对偶图,则满足: G'中每一条边的两个节点对应着G中有公共边的面,包括最外部无限大的面. 直观地讲,红色标出来的图就是蓝色标出的图的对偶图 ...

  8. fzyzojP3979 -- [校内训练20180914]魔法方阵

    原题见CF632F https://blog.csdn.net/Steaunk/article/details/80217764 这个比较神仙了 点边转化, 把max硬生生转化成了路径最大值,再考虑所 ...

  9. 日常训练赛 Problem C – Complete Naebbirac’s sequence

    比赛链接https://vjudge.net/contest/256988#status/17111202012/C/0/ 大意:三个操作,使得输入的数中,从1-n,每一个数出现的次数相同. wa代码 ...

随机推荐

  1. Python的import导入与时间

    一.模块与包 模块,在Python可理解为对应于一个文件.在创建了一个脚本文件后,定义了某些函数和变量.你在其他需要这些功能的文件中,导入这模块,就可重用这些函数和变量.一般用module_name. ...

  2. luogu4172 [WC2006]水管局长

    就是用 lct 维护最小生成树 ref #include <algorithm> #include <iostream> #include <cstdio> #in ...

  3. netty源码分析系列文章

    netty源码分析系列文章 nettynetty源码阅读netty源码分析  想在年终之际将对netty研究的笔记记录下来,先看netty3,然后有时间了再写netty4的,希望对大家有所帮助,这个是 ...

  4. Django笔记 —— 基础部分总结

    最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...

  5. Linux初步——常用简单命令

    散乱的记录,目前是边学边用,以后有机会再整理 curl命令 发起一个HTTP请求,如:curl "http://www.baidu.com" 加上-I选项查看HTTP协议头的信息, ...

  6. 《python核心编程第二版》第5章习题

    5-1 整形 讲讲 Python 普通整型和长整型的区别 答:普通整型 32位,长整数类型能表达的 数值仅仅与你的机器支持的(虚拟)内存大小有关 5-2 运算符(a) 写一个函数,计算并返回两个数的乘 ...

  7. Asp.net core中Migration工具使用的交流分享

    a,ul>li,em{ color:deeppink !important; } h2>a{ text-decoration:none; } ul>li{ padding:3px; ...

  8. [leetcode-635-Design Log Storage System]

    You are given several logs that each log contains a unique id and timestamp. Timestamp is a string t ...

  9. Redis数据类型及操作详解

    Redis数据库,是nosql的一种.与传统关系型数据库(如mysql.sqlserver等)相比,他在处理大数据量上相当有优势,扩展性和可用性高,这是传统型数据库所达不到的. Redis是一个key ...

  10. 如何使用 window.open() 处理ajax请求返回的url: 在本页面打开并防止浏览器拦截

    ajax请求中用window.open()打开请求返回url(例如实现下载功能时),可能会因为跨域问题导致浏览器拦截 解决办法是:在请求前,打开一个窗口,请求成功后将返回的url直接赋值给该窗口的hr ...