【题目大意】

给一棵树,求有多少条路径满足总和-最大值 是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. jpa Specification复杂查询

    public List<Receipts> test(List<String> costIds){ Specification<Receipts> specific ...

  2. Asp.NET Core2.0与 EF的ABP框架入门视频教程

    https://ke.qq.com/course/287301?from=qqchat&ADUIN=1187219916&ADSESSION=1522716499&ADTAG= ...

  3. C++调用Asprise OCR识别图片

    在一个识别软件中发现了Asprise OCR的"身影",上官网查了一下相关信息,发现功能挺强大的,识别印刷体应该不错,遗憾的是好像不能识别中文,不过不知道它对扭曲后的英文识别能力怎 ...

  4. OpenCV入门:(二:加载,显示,修改以及保存图片)

    目标: 1.从图片文件打开图片(imread) 2.显示图片(namedWindow和imshow) 3.转换当前图片为灰色图片(cvtColor) 4.保存图片(imwrite) 代码: #incl ...

  5. js解决img标签加载失败显示默认图片

    问题: 为所有显示楼盘的页面添加一个加载失败的默认图片. 基本思路: img标签中有个onerror属性,专门用来处理加载失败的事件.所以可以用jquery添加onerror属性,在onerror中加 ...

  6. Qt 加载Leap motion 手势识别软件 二次开发 hello world

    研发需要对收拾是被进行精确定位,实现收拾的识别,和在虚拟现实中精确的显示手势在实际世界中的位置. 开始使用的Qt mingw的版本开发,总是函数没有定义,最后发现是leap sdk中需要代育vs的库文 ...

  7. Django学习笔记(一):环境安装与简单实例

    Django学习笔记(一):环境安装与简单实例 通过本文章实现: Django在Windows中的环境安装 Django项目的建立并编写简单的网页,显示欢迎语与当前时间 一.环境安装 结合版本兼容性等 ...

  8. 如何使用remix

    ---恢复内容开始--- 教程 | [Ethereum 智能合约开发笔记]使用 Remix Ajian | 3. Feb, 2018 | 621 次阅读 教程 Remix 开发工具 之前有自己开发过E ...

  9. mysql数据备份和还原

    MySQL是一个永久存储数据的数据库服务器.如果使用MySQLServer,那么需要创建数据库备份以便从崩溃中恢复.mysql提供了一个用于备份的实用程序mysqldump. 1.普通.sql文件中的 ...

  10. laydate日期控件

    <!-- laydate 日期时间控件 下载地址 http://www.layui.com/laydate/ 这里用到版本为 layDate-v5.0.2 下载后将 laydate 文件夹放到项 ...