【UR #14】最强跳蚤
SOL:
我们显然可以发现,我们应该对每一个数质因数分解。
然后发现路径权是平方数等价于两点到根点的权之积为平方,那么就和树没有什么关系了。
我们把每一个点到根的路径权哈希一下就好了。
#include<bits/stdc++.h> #define pii pair<int,int> #define itmp map<pii,int>::iterator #define eho(x) for(int z=head[x];z;z=net[z]) #define mo1 12345679 #define mo2 10000007 #define v fall[z] #define SIZ 10010 #define N 200007 #define M 9000007 #define LL long long #define sight(x) ('0'<=x&&x<='9') using namespace std; map<pii,int> mp; int usd[SIZ],pim[SIZ],Tot,head[N],net[N],fall[N],tot=1,pio; int rs[N][27],siz[N],n,p[M],rx[M]; inline void read(int &x){ static char c; for (c=getchar();!sight(c);c=getchar()); for (x=0;sight(c);c=getchar())x=x*10+c-48; } void write(LL x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(LL x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); } inline void writel(LL x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); } inline void add(int x,int y){ fall[++tot]=y; net[tot]=head[x]; head[x]=tot; } void pre() { for (int i=2;i<SIZ;i++) { if (!usd[i]) pim[++Tot]=i; for (int j=1;j<=Tot&&pim[j]*i<SIZ;j++) { usd[i*pim[j]]=1; if (i%pim[j]==0) break; } } } void Pre(int id,int key){ // if (key==0) return; // cerr<<key<<endl; for (int i=1;i<=Tot;i++) if (key%pim[i]==0) { pio=0; while (key%pim[i]==0) pio^=1,key/=pim[i]; if (pio) rs[id][++siz[id]]=pim[i], rx[++siz[0]]=pim[i]; } if (key!=1) rs[id][++siz[id]]=key,rx[++siz[0]]=key; } void Li() { sort(rx+1,rx+siz[0]+1); for (int i=1;i<n;i++) for (int j=1;j<=siz[i];j++) rs[i][j]=upper_bound(rx+1,rx+siz[0]+1,rs[i][j])-rx; } inline LL qsm(LL x,LL y,LL mo){ static LL anw; for(anw=1;y;y>>=1,x=x*x%mo) if (y&1) anw=anw*x%mo; return anw; } LL xx,yy; void dfs(int x,int fa){ // ha(p); // cerr<<xx<<' '<<yy<<endl; mp[pii(xx,yy)]++; eho(x) if (v^fa) { for (int i=1;i<=siz[z>>1];i++) { if (p[rs[z>>1][i]]) xx-=qsm(2,rs[z>>1][i],mo1),xx=(xx+mo1)%mo1, yy-=qsm(2,rs[z>>1][i],mo2),yy=(yy+mo2)%mo2; else xx+=qsm(2,rs[z>>1][i],mo1),xx=(xx)%mo1, yy+=qsm(2,rs[z>>1][i],mo2),yy=(yy)%mo2; p[rs[z>>1][i]]^=1; } dfs(v,x); for (int i=1;i<=siz[z>>1];i++){ if (p[rs[z>>1][i]]) xx-=qsm(2,rs[z>>1][i],mo1),xx=(xx+mo1)%mo1, yy-=qsm(2,rs[z>>1][i],mo2),yy=(yy+mo2)%mo2; else xx+=qsm(2,rs[z>>1][i],mo1),xx=(xx)%mo1, yy+=qsm(2,rs[z>>1][i],mo2),yy=(yy)%mo2; p[rs[z>>1][i]]^=1; } } } int x,y,w; long long ans; signed main () { // freopen("a.in","r",stdin); read(n); pre(); for (int i=1;i<n;i++) read(x),read(y),read(w),add(x,y),add(y,x), Pre(tot>>1,w); Li(); cerr<<siz[0]<<endl; dfs(1,0); for (itmp x=mp.begin();x!=mp.end();x++) ans+=1ll*(x->second-1)*x->second;//,cerr<<(x->second-1)*x->second<<endl; writeln(ans); }