码迷,mamicode.com
首页 > 其他好文 > 详细

P2634 [国家集训队]聪聪可可(点分治)

时间:2018-10-11 23:53:26      阅读:25      评论:0      收藏:0      [点我收藏+]

标签:getc   head   转化   pre   日常   多少   int   oid   dep   

题意:给你一颗树,询问路径和是3的倍数的路径有多少条

思路:日常搬运点分治,这个题其实是运用了取模,三的倍数其实可以转化为对3取模,然后直接点分治

代码:(一直T,最后发现是getroot时写错了)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int read()
{
    int x=0,w=1;char ch=getchar();
    while ((ch<0||ch>9)&&ch!=-) ch=getchar();
    if (ch==-) w=0,ch=getchar();
    while (ch>=0&&ch<=9) x=(x<<3)+(x<<1)+ch-0,ch=getchar();
    return w?x:-x;
}

const int maxn=20005;
struct edge
{
    int to,next,w;
}a[maxn<<1];
int n,m,k,head[maxn],cnt;
int root,sum,vis[maxn],sz[maxn];
int f[maxn],dep[maxn];
int ans;
int t[5];
int MAX(int x,int y)
{
    return x>y?x:y;
}
int gcd(int x,int y)
{
    return y==0?x:gcd(y,x%y);
}
void addedge(int u,int v,int w)
{
    a[++cnt].to=v;
    a[cnt].next=head[u];
    a[cnt].w=w;
    head[u]=cnt;
}

void getroot(int u,int fa)
{
    sz[u]=1;f[u]=0;
    for(int e=head[u];e;e=a[e].next){
        int v=a[e].to;if(v==fa||vis[v])continue;
        getroot(v,u);
        sz[u]+=sz[v];
        f[u]=MAX(f[u],sz[v]);
    }
    f[u]=MAX(f[u],sum-sz[u]);
    if(f[u]<f[root])root=u;
}
void getdeep(int u,int fa)
{
    t[dep[u]%3]++;
    for(int e=head[u];e;e=a[e].next){
        int v=a[e].to;if(v==fa||vis[v])continue;
        dep[v]=dep[u]+a[e].w;
        getdeep(v,u);
    }
}
int calc(int u,int d0)
{
    dep[u]=d0;t[0]=t[1]=t[2]=0;
    getdeep(u,0);
    return t[0]*t[0]+2*t[1]*t[2];
}
void solve(int u)
{
    ans+=calc(u,0);vis[u]=1;
    for(int e=head[u];e;e=a[e].next){
        int v=a[e].to;if(vis[v])continue;
        ans-=calc(v,a[e].w);
        sum=sz[v];root=0;
        getroot(v,0);
        solve(root);
    }
}
int main()
{
    n=read();
    for(int i=1;i<n;++i){
        int u=read(),v=read(),w=read();
        addedge(u,v,w);
        addedge(v,u,w);
    }
    f[0]=sum=n;
    getroot(1,0);
    solve(root);
    int as=gcd(ans,n*n);
    ans/=as;
    printf("%d/%d\n",ans,n*n/as);
    return 0;
}

 

P2634 [国家集训队]聪聪可可(点分治)

标签:getc   head   转化   pre   日常   多少   int   oid   dep   

原文地址:https://www.cnblogs.com/lalalatianlalu/p/9775528.html

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!