#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1000005
using namespace std;
int n,m,tot,sum,root,top,stack[maxn][2],h[maxn],way[maxn*2],Next[maxn*2],w[maxn*2],size[maxn],power_10[maxn],ni[maxn];
long long ans;
bool v[maxn];
int read(){
int x=0,f=1;char ch;
for(ch=getchar();ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct Hash{
#define mod 555616
int cnt,head[mod],fuck[maxn],val[maxn],num[maxn];
void clear(int x){head[x%mod]=0;}
void insert(int x){
for(int i=head[x%mod];i;i=fuck[i])if(val[i]==x){num[i]++;return;}
++cnt;val[cnt]=x;fuck[cnt]=head[x%mod];head[x%mod]=cnt;num[cnt]=1;
}
int find(int x){
for(int i=head[x%mod];i;i=fuck[i])if(val[i]==x)return num[i];
return 0;
}
}hash;
void insert(int x,int y,int z){way[++tot]=y;Next[tot]=h[x];h[x]=tot;w[tot]=z;}
void exgcd(int a,int b,int &x,int &y){
if(b==0){x=1;y=0;return;}
int tx,ty;exgcd(b,a%b,tx,ty);
x=ty;y=tx-a/b*ty;
}
int getni(){
int x,y;exgcd(10,m,x,y);
x=(x%m+m)%m;return x;
}
void getroot(int x,int fa){
size[x]=1;int pps=0;
for(int j=h[x];j;j=Next[j])if(way[j]!=fa&&!v[way[j]]){
getroot(way[j],x);size[x]+=size[way[j]];pps=max(pps,size[way[j]]);
}
if(max(pps,sum-size[x])<=sum/2)root=x;
}
void reverse(){for(int i=1;i<=top/2;i++)swap(stack[i][0],stack[top-i+1][0]),swap(stack[i][1],stack[top-i+1][1]);}
void calc(int x,int fa,int len,int num){
ans+=hash.find((1LL*(-num)*ni[len]%m+m)%m);
for(int j=h[x];j;j=Next[j])if(way[j]!=fa&&!v[way[j]])calc(way[j],x,len+1,(1LL*num*10+w[j])%m);
}
void change(int x,int fa,int len,int num,int op){
if(op)hash.insert(num);else hash.clear(num);
for(int j=h[x];j;j=Next[j])if(way[j]!=fa&&!v[way[j]])change(way[j],x,len+1,(1LL*w[j]*power_10[len]+num)%m,op);
}
void calc(int x,int op){
if(op)hash.insert(0);
for(int i=1;i<=top;i++)calc(stack[i][0],x,1,stack[i][1]),change(stack[i][0],x,1,stack[i][1],1);
if(op)ans+=hash.find(0)-1,hash.clear(0);
for(int i=1;i<=top;i++)change(stack[i][0],x,1,stack[i][1],0);
}
void work(int x,int s){
top=0;v[x]=1;
for(int j=h[x];j;j=Next[j])if(!v[way[j]])++top,stack[top][0]=way[j],stack[top][1]=w[j];
calc(x,1);reverse();calc(x,0);
for(int j=h[x];j;j=Next[j])if(!v[way[j]]){
sum=size[way[j]]>size[x]?s-size[x]:size[way[j]];
getroot(way[j],x);work(root,sum);
}
}
int main(){
n=read();m=read();
power_10[0]=ni[0]=1;
for(int i=1,j=getni();i<=n;i++)power_10[i]=1LL*power_10[i-1]*10%m,ni[i]=1LL*ni[i-1]*j%m;
for(int i=1,x,y,z;i<n;i++){
x=read();y=read();z=read()%m;
insert(x,y,z);insert(y,x,z);
}
sum=n;getroot(0,-1);work(root,sum);
printf("%lld\n",ans);
return 0;
}

  

最新文章

  1. Java中,调试按钮的作用
  2. 第十周 psp
  3. 【代码笔记】iOS-点击加号增加书架,点击减号减少书架
  4. jquery通过ajax方法获取json数据不执行success回调
  5. POJ 2942 Knights of the Round Table(双连通分量)
  6. Cygwin环境编译/usr/include/sys/_types.h:72:20: 致命错误:stddef.h:can not found
  7. 学习PHP爬虫--《Webbots、Spiders和Screen Scrapers:技术解析与应用实践(原书第2版)》
  8. Matalab之模糊KMeans原理
  9. 前端制作中,IE6还有必要兼容吗?
  10. python 装饰器、内部函数、闭包简单理解
  11. javaWEB总结(4):ServletContext对象方法
  12. elasticsearch 学习笔记
  13. [转]在Mac系统中安装配置Tomcat及和Eclipse 配置
  14. [Swift]LeetCode1027. 最长等差数列 | Longest Arithmetic Sequence
  15. &lt;!--#include virtual=&#39;head.html&#39;--&gt;代码复用
  16. springMVC的配置与使用
  17. ----regular expression in js----
  18. 网络编程_IP对象_InetAddress
  19. python-flask-session和scoped_session区别
  20. 获取数据库表中自增长最新的id

热门文章

  1. Memcached快递上手之C#
  2. CEGUI添加自定义控件
  3. 在Linux使用GCC编译C语言共享库
  4. Windows 7/8 64位下安装64位Apache 2.4.7
  5. js中的屏蔽
  6. 开始MVC5之旅
  7. CSS中文字体的英文名称 – 前台开发必备
  8. Orchard网上商店模块
  9. 实现pow(int x, int y),即x的y次方 ; 异或交换两个数;
  10. 简明CSS属性:定位