题意:

  给出一个树,每条边上写了一个数字,给出一个P,求有多少条路径按顺序读出的数字可以被P整除。保证P与10互质。

分析:

  统计满足限制的路径,我们首先就想到了点分治。

  随后我们就需要考量,我们是否能统计过某个点的合法路径。我们看,由题目性质,我们可以求对于一个根,所有点到根的路径组成的数,以及根到所有点的路径所组成的数。然后我们就可以对前者开一个数组(其实是一个map容器),后者在上面查询,然后用点分治的去重套路,保证答案不重不漏。

代码:

 #include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=,inf=0x3f3f3f3f;
struct node{int y,z,nxt;}e[N*];int ans;
int sm,h[N],c=,vis[N],d[N],siz[N],mx[N];
int rt,n,m,pw[N],tot,dis[N];map<int,int>mp;
void add(int x,int y,int z){
e[++c]=(node){y,z,h[x]};h[x]=c;
e[++c]=(node){x,z,h[y]};h[y]=c;
} void getrt(int x,int fa){
siz[x]=;mx[x]=;
for(int i=h[x],y;i;i=e[i].nxt)
if((y=e[i].y)!=fa&&!vis[y]){
getrt(y,x);siz[x]+=siz[y];
mx[x]=max(mx[x],siz[y]);
} mx[x]=max(mx[x],sm-siz[x]);
if(mx[x]<mx[rt]) rt=x;return ;
} void exgcd(int a,int b,int &d,int &x,int &y){
if(!b) d=a,x=,y=;
else exgcd(b,a%b,d,y,x),y-=x*(a/b);
} int inv(int a,int p){
int x,y,d;exgcd(a,p,d,x,y);
return d==?(x%p+p)%p:-;
} void dfs(int x,int fa,int v1,int v2,int dep){
if(dep){
mp[v2%m]++;dis[++tot]=v1;d[tot]=dep;
} for(int i=h[x],y;i;i=e[i].nxt)
if((y=e[i].y)!=fa&&!vis[y]){
dfs(y,x,(v1*%m+e[i].z)%m,
(v2+e[i].z*pw[dep]%m)%m,dep+);
} return ;
} int calc(int x,int v,int op){
int res=;tot=;mp.clear();
dfs(x,,v,v,op);
for(int i=;i<=tot;i++){
int val=(m-dis[i]*inv(pw[d[i]],m)%m)%m;
if(mp.find(val)!=mp.end()) res+=mp[val];
if(!op) res+=(dis[i]==);
} if(!op) res+=mp[];return res;
} void solve(int x){
ans+=calc(x,,);vis[x]=;
for(int i=h[x],y;i;i=e[i].nxt)
if(!vis[y=e[i].y]){
ans-=calc(y,e[i].z,);
mx[rt=]=inf;sm=siz[y];
getrt(y,);solve(rt);
} return ;
} signed main(){
scanf("%lld%lld",&n,&m);
for(int i=,x,y,z;i<n;i++)
scanf("%lld%lld%lld",&x,&y,&z),
add(x+,y+,z);
pw[]=;for(int i=;i<=n;i++)
pw[i]=1ll*pw[i-]*%m;
mx[rt=]=inf;sm=n;
getrt(,);solve(rt);
printf("%lld\n",ans);
return ;
}

点分治

CF716E Digit Tree 点分治的更多相关文章

  1. CF 716E. Digit Tree [点分治]

    题意:一棵树,边上有一个个位数字,走一条路径会得到一个数字,求有多少路径得到的数字可以整除\(P\) 路径统计一般就是点分治了 \[ a*10^{deep} + b \ \equiv \pmod P\ ...

  2. 【Codeforces715C&716E】Digit Tree 数学 + 点分治

    C. Digit Tree time limit per test:3 seconds memory limit per test:256 megabytes input:standard input ...

  3. 【Codeforces 715C】Digit Tree(点分治)

    Description 程序员 ZS 有一棵树,它可以表示为 \(n\) 个顶点的无向连通图,顶点编号从 \(0\) 到 \(n-1\),它们之间有 \(n-1\) 条边.每条边上都有一个非零的数字. ...

  4. Codeforces 716 E Digit Tree

    E. Digit Tree time limit per test 3 seconds memory limit per test 256 megabytes input standard input ...

  5. 【题解】Digit Tree

    [题解]Digit Tree CodeForces - 716E 呵呵以为是数据结构题然后是淀粉质还行... 题目就是给你一颗有边权的树,问你有多少路径,把路径上的数字顺次写出来,是\(m\)的倍数. ...

  6. 【BZOJ-1468】Tree 树分治

    1468: Tree Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1025  Solved: 534[Submit][Status][Discuss] ...

  7. HDU 4812 D Tree 树分治+逆元处理

    D Tree Problem Description   There is a skyscraping tree standing on the playground of Nanjing Unive ...

  8. POJ 1741 Tree 树分治

    Tree     Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...

  9. [bzoj 1468][poj 1741]Tree [点分治]

    Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...

随机推荐

  1. 51nod 1247 可能的路径(gcd)

    传送门 题意 略 分析 有以下结论 \(1.(x,y)->(y,x)\) \(2.(x,y)->(a,b)==>(a,b)->(x,y)\) 证明 做如下变换 \((a,b)- ...

  2. HDU 5101

    hdoj5101 lower_bound函数: 题意: 从两个不同集合拿出两个数,加的和大于k的可行的方案数 思路: 答案=从所有数中选择的两个加和大于k的数的方案数-在同一个集合中选择的两个加和大于 ...

  3. Codeforces732E Sockets

    首先检测有木有和Computer匹配的Socket,如果有则将其匹配. 然后将所有没有匹配的Socket连上Adapter,再去检测有木有Computer与Socket匹配. 重复这个操作31次,所有 ...

  4. IT兄弟连 Java Web教程 经典面试题2

    1.Servlet的工作流程? Servlet是运行在Servlet容器中的,由Servlet容器来负责Servlet实例的查找.创建以及整个生命周期的管理,Servlet整个生命周期可以分为四个阶段 ...

  5. CentOS服务器下安装配置SSL

    https是一个安全的访问方式,数据在传输过程中是加密的,https基于SSL. 一.安装apache和ssl模块 1.安装apache #yum install httpd 2.安装ssl模块 #y ...

  6. camshift.py OpenCv例程阅读

    源码在这 #!/usr/bin/env python ''' Camshift tracker ================ This is a demo that shows mean-shif ...

  7. PHP常见的输出语句 echo()、print()、print_r()、var_dump()、pinrtf()之间的区别

    echo().print().print_r().var_dump().pinrtf()之间的区别 1.print() :简单输出语句,可以输出字符串,变量.表达式等单项的值!(不能输出数组.对象等复 ...

  8. 转 sql 查出一张表中重复的所有记录数据

    select * from DB_PATCH awhere lower(a.db_name) in (select lower(db_name) from DB_PATCH group by lowe ...

  9. 通过表单展示不一样的页面(input对象)

    表单中包含不一样的样式,不同功能的提交数据的方式.在许多页面中,浏览者不经意间已经不断在使用表单的功能,如留言,设置自己的密码或者是复选框,下拉列表等. input对象下的多种表单表现形式: 通常在页 ...

  10. Visual Studio Code配置 HTML 开发环境

    Visual Studio Code配置 HTML 开发环境 https://v.qq.com/x/page/l0532svf47c.html?spm=a2h0k.11417342.searchres ...