求调,悬棺
查看原帖
求调,悬棺
632955
伊地知虹夏楼主2024/3/30 19:02

rt,用的是淀粉质

#include<bits/stdc++.h> 
using namespace std;
const int N = 1e5 + 5;
#define int long long
int n,m;
int exgcd(int &x,int &y,int a,int b){
	if(a % b == 0) return x = 0,y = 1,b;
	int g = exgcd(y,x,b,a%b);
	return y -= a/b,g;
}
int iv[N],pw[N];
vector<pair<int,int> > G[N];
map<int,int> M;
int sz[N],rt = -1;
bool del[N];
void Fin(int x,int fa){
	int mxs = 0;
	sz[x] = 1;
	for(auto nxt:G[x]){
		int y = nxt.first;
		if(y == fa || del[y]) continue;
		Fin(y,x);
		if(rt != -1) return ;
		sz[x] += sz[y],mxs = max(mxs,sz[y]);
	}
	mxs = max(mxs,n - sz[x]);
	if(mxs <= (n >> 1))
		sz[fa] = n - sz[x],rt = x;
	return ;
}
int st[N],tp,ans;
void Cal(int x,int fa,int a,int b,int cnt){
	int l = (m - a * iv[cnt] % m) % m;
	if(l == 0) ++ ans;
	ans += M[l],st[++ tp] = b;
	for(auto nxt:G[x]){
		int y = nxt.first,w = nxt.second;
		if(y == fa || del[y]) continue;
		Cal(y,x,(a * 10 + w) % m,(b + w * pw[cnt] % m) % m,cnt + 1);
	}
}
void Sol(int x){
	for(auto nxt:G[x]){
		int y = nxt.first,w = nxt.second;
		if(del[y]) continue;
		Cal(y,x,w,w,1);
		while(tp) ++ M[st[tp --]];
	}
	reverse(G[x].begin(),G[x].end()),M.clear();
	for(auto nxt:G[x]){
		int y = nxt.first,w = nxt.second;
		if(del[y]) continue;
		Cal(y,x,w,w,1);
		while(tp) ++ M[st[tp --]];
	}
	del[x] = 1,M.clear();
	for(auto nxt:G[x]){
		int y = nxt.first,w = nxt.second;
		if(del[y]) continue;
		n = sz[y],rt = -1,Fin(y,0),Sol(rt);
	}
}
signed main(){
	cin >> n >> m;
	for(int i = 1,x,y,w;i < n;i ++){
		cin >> x >> y >> w;
		++ x, ++ y;
		G[x].push_back({y,w});
		G[y].push_back({x,w});
	}
	int x,y;
	exgcd(x,y,10,m);
	x = (x % m + m) % m;
	iv[0] = pw[0] = 1;
	for(int i = 1;i <= n;i ++)
		iv[i] = iv[i - 1] * x % m,
		pw[i] = pw[i - 1] * 10 % m;
	rt = -1,Fin(1,0),Sol(rt);
//	cout << rt << '\n';
	cout << ans << '\n';
	return 0;
}
2024/3/30 19:02
加载中...