[BZOJ2152]聪聪可可(点分治)
生活随笔
收集整理的這篇文章主要介紹了
[BZOJ2152]聪聪可可(点分治)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
有點模板的點分治,
設d[i](0≤i≤2)表示路徑距離%3為i的數量
那么顯然,方案數就為d[1]*d[2]*2+d[0]2
Code
#include <cstdio> #include <algorithm> #define N 20010 using namespace std;struct info{int to,nex,w;}e[N*2]; int n,tot,head[N],sum,f[N],sz[N],d[3],Ans,rt; bool vis[N];int gcd(int a,int b){return b?gcd(b,a%b):a;} void Link(int u,int v,int w){e[++tot].to=v,e[tot].w=w,e[tot].nex=head[u];head[u]=tot; }inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f; }void getrt(int u,int fa){sz[u]=1,f[u]=0;for(int i=head[u];i;i=e[i].nex){int v=e[i].to;if(v==fa||vis[v]) continue;getrt(v,u);f[u]=max(f[u],sz[v]);sz[u]+=sz[v];}f[u]=max(f[u],sum-sz[u]);if(f[rt]>f[u]) rt=u; }void getdep(int u,int fa,int ddd){d[ddd]++;for(int i=head[u];i;i=e[i].nex){int v=e[i].to;if(v==fa||vis[v]) continue;getdep(v,u,(ddd+e[i].w)%3);} }int calc(int u,int ddd){d[0]=d[1]=d[2]=0;getdep(u,0,ddd%3);return d[1]*d[2]*2+d[0]*d[0]; }void solve(int u){Ans+=calc(u,0);vis[u]=1;for(int i=head[u];i;i=e[i].nex){int v=e[i].to;if(vis[v]) continue;Ans-=calc(v,e[i].w);sum=sz[v];getrt(v,rt=0);solve(rt);} }int main(){n=read();for(int i=1;i<n;++i){int u=read(),v=read(),w=read();Link(u,v,w),Link(v,u,w);}sum=n,f[0]=1e9,getrt(1,0);solve(rt);int f=gcd(n*n,Ans);printf("%d/%d\n",Ans/f,n*n/f);return 0; }?
轉載于:https://www.cnblogs.com/void-f/p/9107521.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的[BZOJ2152]聪聪可可(点分治)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Django 框架02: 模型与站点
- 下一篇: Runtime应用