[Codeforces 715C] Digit Tree
[题目链接]
https://codeforces.com/contest/715/problem/C
[算法]
考虑点分治
一条路径(x , y)合法当且仅当 : d(x) * 10 ^ dep(x) + d(y) = 0(mod m) , 其中d(u)表示u到分治重心路径上数字拼接起来所形成的数
统计答案时 , 我们只需维护一个map , 维护10 ^ -dep(u) * d(u) (mod m)
然后计算每个点的贡献即可
时间复杂度 : O(NlogN ^ 2)
[代码]
#include<bits/stdc++.h>
using namespace std;
#define N 100010
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull; struct edge
{
int to , w , nxt;
} e[N << ]; int n , m , tot , len , root;
ll ans;
int pw[N] , head[N] , size[N] , weight[N] , D[N] , depth[N];
bool visited[N];
map<int , int> mp; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void addedge(int u , int v , int w)
{
++tot;
e[tot] = (edge){v , w , head[u]};
head[u] = tot;
}
inline void getroot(int u , int par , int total)
{
size[u] = ;
weight[u] = ;
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v == par || visited[v]) continue;
getroot(v , u , total);
size[u] += size[v];
chkmax(weight[u] , size[v]);
}
chkmax(weight[u] , total - size[u]);
if (weight[u] < weight[root]) root = u;
}
inline void exgcd(int a , int b , int &x , int &y)
{
if (b == )
{
x = ;
y = ;
} else
{
exgcd(b , a % b , y , x);
y -= a / b * x;
}
}
inline int inv(int a)
{
int x , y;
exgcd(a , m , x , y);
return (x % m + m) % m;
}
inline void dfs(int u , int par , int d1 , int d2)
{
if (depth[u] > ) ++mp[(1ll * d2 % m * inv(pw[depth[u]] % m)) % m];
D[++len] = d1;
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to , w = e[i].w;
if (v == par || visited[v]) continue;
depth[v] = depth[u] + ;
dfs(v , u , (1ll * w * pw[depth[v] - ] % m + d1) % m , (10ll * d2 % m + w) % m);
}
}
inline ll calc(int u , int d)
{
mp.clear();
len = ;
if (!d) dfs(u , - , , );
else dfs(u , - , d % m , d % m);
ll res = ;
for (int i = ; i <= len; ++i)
{
int goal = ((m - D[i]) % m + m) % m;
res += (ll)mp[goal];
if (!d && !D[i]) ++res;
}
return res;
}
inline void work(int u)
{
visited[u] = true;
depth[u] = ;
ans += calc(u , );
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to , w = e[i].w;
if (visited[v]) continue;
depth[v] = ;
ans -= calc(v , w);
}
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (visited[v]) continue;
root = ;
getroot(v , u , size[v]);
work(root);
}
} int main()
{ read(n); read(m);
pw[] = ;
for (int i = ; i <= n; ++i) pw[i] = 1ll * pw[i - ] * % m;
for (int i = ; i < n; ++i)
{
int u , v , w;
read(u); read(v); read(w);
++u; ++v;
addedge(u , v , w);
addedge(v , u , w);
}
weight[] = n;
root = ;
getroot( , , n);
work(root);
ans -= n;
printf("%I64d\n" , ans); return ; }
[Codeforces 715C] Digit Tree的更多相关文章
- 【Codeforces 715C】Digit Tree(点分治)
Description 程序员 ZS 有一棵树,它可以表示为 \(n\) 个顶点的无向连通图,顶点编号从 \(0\) 到 \(n-1\),它们之间有 \(n-1\) 条边.每条边上都有一个非零的数字. ...
- Codeforces 716 E Digit Tree
E. Digit Tree time limit per test 3 seconds memory limit per test 256 megabytes input standard input ...
- 【题解】Digit Tree
[题解]Digit Tree CodeForces - 716E 呵呵以为是数据结构题然后是淀粉质还行... 题目就是给你一颗有边权的树,问你有多少路径,把路径上的数字顺次写出来,是\(m\)的倍数. ...
- 【Codeforces715C&716E】Digit Tree 数学 + 点分治
C. Digit Tree time limit per test:3 seconds memory limit per test:256 megabytes input:standard input ...
- Problem - D - Codeforces Fix a Tree
Problem - D - Codeforces Fix a Tree 看完第一名的代码,顿然醒悟... 我可以把所有单独的点全部当成线,那么只有线和环. 如果全是线的话,直接线的条数-1,便是操作 ...
- Codeforces 765 E. Tree Folding
题目链接:http://codeforces.com/problemset/problem/765/E $DFS子$树进行$DP$ 大概分以下几种情况: 1.为叶子,直接返回. 2.长度不同的路径长度 ...
- codeforces 570 D. Tree Requests 树状数组+dfs搜索序
链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds mem ...
- CodeForces 383C Propagating tree
Propagating tree Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces ...
- 【19.77%】【codeforces 570D】Tree Requests
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
随机推荐
- SolidEdge 工程图中如何给零件添加纹理或贴图
格式-检视-勾选纹理 选中一个零件之后,点击格式-面,在纹理选项卡中找到纹理的贴图 最后效果如下图所示,如果不勾选检视纹理,则虽然的确贴图了,但是不显示出来给你看.如果贴图文件没了,也不会显示 ...
- Path SumI、II——给出一个数,从根到子的和等于它
I.Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up a ...
- Codeforces Round #277 (Div. 2)D(树形DP计数类)
D. Valid Sets time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- 在没有安装access的电脑上读写.mdb文件
在微软官方下载MDAC access数据库访问组件即可
- 显示和隐藏Mac隐藏文件的命令
显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool true 隐藏Mac隐藏文件的命令:defaults writ ...
- XML(四)dom4j解析XML
使用dom4j须要导入jar包 jar包下载地址:http://pan.baidu.com/s/1o65jWRw 将dom4j-1.6.1.jar包导入Eclipse book2.xml <?x ...
- [oracle]pl/sql --分页过程demo
这句sql能够用来查询一张表中的特定位置的记录 --查询的方法获取分页的语句 select *from (select t1.*,rownum rn from (select *from books) ...
- Install Server Backup Manager on CentOS, RHE, and Fedora
Skip to end of metadata Added by Internal, last edited by Internal on Aug 25, 2014 Go to start of me ...
- 通过代码实现自动判断是手机端还是PC端跳转
<!-- 2017/09/13 跳转手机页面 start by 小鬼PSer --> <meta name="mobile-agent" content=&quo ...
- 在JS中将JSON的字符串解析成JSON数据格式
使用eval函数来解析 <script> var data="{root: [{name:'1',value:'0'},{name:'6101',value:'北京市'},{na ...