zoukankan      html  css  js  c++  java
  • 【题解】聪聪可可

    题目戳我

    ( ext{Solution:})

    显然题目所求和“大规模处理树上路径问题”这一特点相符。考虑点分治。

    由于题目只要求对于(3)的倍数,所以我们可以分别记录(tmp[i])表示到当前点路径长度为(i)的路径数目。(iin ext{{0,1,2}})

    若我们知道了这三个量,则此处的答案就是(tmp[0]^2+2*tmp[1]*tmp[2].)

    (tmp[1]*tmp[2])之所以要乘以(2)是因为对于点对((u,v),(v,u))它们算作两种。

    (tmp[0]^2)之所以不需要乘以(2,)是因为它本身就是一个集合的自我组合。也就是说在平方的过程中,我们已经把上述情况考虑过了。

    (tmp[0]^2)的组合意义就是从(tmp[0])中任选两个点(注意选择点可以重合)相组合。而(tmp[1]*tmp[2])虽然也是这个意思,但由于它们分别属于两个不同集合,所以我们最后计数需要把它们乘以(2.)

    剩下的就是点分治模板了。找重心,计数的时候容斥一下,最后写个(gcd)就过了。

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=100010;
    inline int gcd(int x,int y){return !y?x:gcd(y,x%y);}
    int tot,head[MAXN],siz[MAXN],Siz,ans,n;
    struct edge{int nxt,to,dis;}e[MAXN];
    inline void link(int x,int y,int w){e[++tot].to=y;e[tot].nxt=head[x];e[tot].dis=w;head[x]=tot;}
    inline int add(int x,int y){return ((x+y)%3);};
    int mson[MAXN],ms,rt,dis[MAXN];
    const int inf=(1<<30);
    bitset<MAXN>vis;
    void Gr(int x,int fa){
    	siz[x]=1;mson[x]=0;
    	for(int i=head[x];i;i=e[i].nxt){
    		int j=e[i].to;
    		if(vis[j]||j==fa)continue;
    		Gr(j,x);siz[x]+=siz[j];
    		if(siz[j]>mson[x])mson[x]=siz[j];
    	}
    	if(Siz-siz[x]>mson[x])mson[x]=Siz-siz[x];
    	if(ms>mson[x])ms=mson[x],rt=x;
    }
    int t,tmp[4];
    void Getdis(int x,int fa,int d){
    	dis[++t]=(d%3);tmp[dis[t]]++;
    	for(int i=head[x];i;i=e[i].nxt){
    		int j=e[i].to;
    		if(j==fa||vis[j])continue;
    		Getdis(j,x,add(d,e[i].dis));
    	}
    }
    int solve(int x,int d){
    	t=0;tmp[1]=tmp[0]=tmp[2]=0;
    	Getdis(x,0,d);return (tmp[0]*tmp[0]+tmp[1]*tmp[2]*2);
    }
    void work(int x,int s){
    	vis[x]=1;ans+=solve(x,0);
    	for(int i=head[x];i;i=e[i].nxt){
    		int j=e[i].to;
    		if(vis[j])continue;
    		ans-=solve(j,e[i].dis);
    		ms=inf;rt=0;Siz=siz[j]<siz[x]?siz[x]:(s-siz[x]);
    		Gr(j,0);work(rt,Siz);
    	}
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<n;++i){
    		int x,y,z;
    		scanf("%d%d%d",&x,&y,&z);
    		link(x,y,z);link(y,x,z);
    	}
    	rt=0;ms=inf;Siz=n;Gr(1,0);work(rt,n);
    	int g=gcd(n*n,ans);
    	printf("%d",ans/g);putchar('/');
    	printf("%d
    ",n*n/g);
    	return 0;
    } 
    
  • 相关阅读:
    CF919F A Game With Numbers
    CF1005F Berland and the Shortest Paths
    CF915F Imbalance Value of a Tree
    CF1027F Session in BSU
    CF1029E Tree with Small Distances
    CF1037E Trips
    CF508E Arthur and Brackets
    CF1042F Leaf Sets
    [HNOI2012]永无乡
    [BZOJ1688][Usaco2005 Open]Disease Manangement 疾病管理
  • 原文地址:https://www.cnblogs.com/h-lka/p/13540404.html
Copyright © 2011-2022 走看看