[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 ...
随机推荐
- 无向图的点双连通分量(tarjan模板)
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #i ...
- MySQL双主热备问题处理
1. Slave_IO_Running: No mysql> show slave status\G *************************** 1. row *********** ...
- LeetCode 第 3 题(Longest Substring Without Repeating Characters)
LeetCode 第 3 题(Longest Substring Without Repeating Characters) Given a string, find the length of th ...
- pjblog支持QQ、新浪微博一键登录
转载地址: http://www.ruisoftcn.com/blog/article.asp?id=955
- UVA 10042 Smith Numbers(数论)
Smith Numbers Background While skimming his phone directory in 1982, Albert Wilansky, a mathematicia ...
- MyBatis学习(二):与Spring整合(非注解方式配置MyBatis)
搭建SpringMVC的-->传送门<-- 一.环境搭建: 目录结构: 引用的JAR包: 如果是Maven搭建的话,pom.xml的配置如下: <?xml version=" ...
- linux 块设备驱动(四)——简单的sbull实例
#include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> # ...
- 05 referer头与防盗链
像上图中的这个效果,当我们在网页里引用站外图片时,常出现这样的情况. ??? 服务器是怎么样知道,这个图片是在站外被引用的呢? 还有在网站的统计结果,统计用户从何而来,如下图 ??? 统计时,是如何得 ...
- Rest Api(转载)
来源:http://www.cnblogs.com/springyangwc/archive/2012/01/18/2325784.html 概述 REST 从资源的角度来观察整个网络,分布在各处的资 ...
- IGP和EGP(转载)
AS(自治系统) - 也称为路由域,是指一个共同管理区域内的一组路由器.例如公司的内部网络和 Internet 服务提供商的网络.由于 Internet 基于自治系统,因此既需要使用内部路由协议,也需 ...