[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 ...
随机推荐
- iOS开发 编码规范
转至 http://www.cnblogs.com/celestial/archive/2012/06/30/2571417.html 编码规范 一.文档结构管理 1.建立Libraries文件夹 ...
- CSRF攻击 & XSS攻击
之前有几篇文章写了 SQL注入类问题: http://www.cnblogs.com/charlesblc/p/5987951.html (介绍) http://www.cnblogs.com/cha ...
- TI C66x DSP 四种内存保护问题 -之- CPU訪问corePac内部资源时的内存保护问题
CPU訪问corePac内部资源(L1.L2)时的内存保护(通过设置内存的訪问权限实现)等问题请參考以下两个blog.已经叙述的非常具体. "TI C66x DSP 系统events及其应用 ...
- 设计模式——介绍与工厂模式(扁平管理模式VS职业经理人模式)
本文主要对设计模式进行大概解说.特别是对工厂模式进行简明的解析: 一.设计模式的分类 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式. ...
- ASP.Net MVC开发基础学习笔记(8):新建数据页面
前言 前面解说了怎样创建一个查询页面并给查询页面加入排序.搜索及分页功能.今天我们来讲讲怎样向这个列表加入数据. 解说的顺序将依照加入数据的步骤的时间顺序来进行,方便大家理清逻辑关系. 本节将涉 ...
- python(26)- 面向对象补充Ⅱ
一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)判断obj是否是类 cls 的对象 class Foo(object): ...
- MySQL中文显示乱码
http://blog.csdn.net/acmain_chm/article/details/4174186
- RYU改动监听port Mininet在custom自建拓扑和连接到指定控制器命令解释
1.RYU控制器改动监听port 在ryu/ryu/ofproto以下的ofproto_common.py watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc ...
- LeetCode(155)题解--Min Stack
https://leetcode.com/problems/min-stack/ 题目: Design a stack that supports push, pop, top, and retrie ...
- [Phoenix] 四、加盐表
摘要: 在密码学中,加盐是指在散列之前将散列内容(例如:密码)的任意固定位置插入特定的字符串.这个在散列中加入字符串的方式称为“加盐”.其作用是让加盐后的散列结果和没有加盐的结果不相同,在不同的应用情 ...