【题目大意】

给一棵树,求有多少条路径满足总和-最大值 是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. Git 相关工具及教程地址

    一.Git GUI 客户端 Git 客户端下载(Windows) TortoiseGit 客户端下载(Windows) Sourcetree 客户端下载(Windows.Mac) Git Extens ...

  2. 怎么使用pipenv管理你的python项目

    原文链接:https://robots.thoughtbot.com/how-to-manage-your-python-projects-with-pipenv 翻译者:Jiong 在thought ...

  3. CSS3 :animation 动画

    CSS3动画分为二部份: 1.定义动画行为: 使用@keyframes定义动画行为,有两种方式: 方式一:仅定义动画起始样式,与动画结束样式 @keyframes (动画行为名称) { from {b ...

  4. python 网络篇(网络编程)

    一.楔子 你现在已经学会了写python代码,假如你写了两个python文件a.py和b.py,分别去运行,你就会发现,这两个python的文件分别运行的很好.但是如果这两个程序之间想要传递一个数据, ...

  5. CodeForces-1132C Painting the Fence

    题目链接 https://vjudge.net/problem/CodeForces-1132C 题面 Description You have a long fence which consists ...

  6. Leetcode 679.24点游戏

    24点游戏 你有 4 张写有 1 到 9 数字的牌.你需要判断是否能通过 *,/,+,-,(,) 的运算得到 24. 示例 1: 输入: [4, 1, 8, 7] 输出: True 解释: (8-4) ...

  7. cmd命令笔记

    查看端口信息:netstat -ano eg. netstat -ano|findstr 0.0.0.0:443 根据pid查看进程信息等:wmic process get name,executab ...

  8. day-12 python实现简单线性回归和多元线性回归算法

    1.问题引入  在统计学中,线性回归是利用称为线性回归方程的最小二乘函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析.这种函数是一个或多个称为回归系数的模型参数的线性组合.一个带有一个自变 ...

  9. Java项目启动时候报Neither the JAVA_HOME nor the JRE_HOME environment variable is defined 解决办法

    今天在发布Java项目的时候又遇到    Neither the JAVA_HOME nor the JRE_HOME environment variable is defined  At leas ...

  10. Week2 Teamework from Z.XML 软件分析与用户需求调查(四)Bing桌面及助手的现状与发展

    一.Bing搜索的相关背景 第一,必应搜索前几年的发展重点在于欧美市场,并且取得了一定的成效:根据 Hitwise 的统计数据,Bing 在 2011年3 月份市场占有率突破了 30% 大关,达到 3 ...