zoukankan      html  css  js  c++  java
  • bzoj2152 / P2634 [国家集训队]聪聪可可(点分治)

    P2634 [国家集训队]聪聪可可

    淀粉质点分治板子

    边权直接 mod 3

    直接点分治统计出所有的符合条件的点对再和总方案数约分

    至于约分.....gcd搞搞就好辣

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    inline int Max(int a,int b){return a>b?a:b;}
    void read(int &x){
        static char c=getchar();x=0;
        while(c<'0'||c>'9') c=getchar();
        while('0'<=c&&c<='9') x=x*10+(c^48),c=getchar();
    }
    #define N 20005
    inline int M(int x){return x<3?x:x-3;}
    int n,rt,sum,ans,tot,mxd[N],siz[N],dis[N],ra[N],rb[3];bool vis[N];
    int cnt,hd[N],nxt[N<<1],ed[N],poi[N<<1],val[N<<1];
    void adde(int x,int y,int v){
        nxt[ed[x]]=++cnt; hd[x]=hd[x]?hd[x]:cnt;
        ed[x]=cnt; poi[cnt]=y; val[cnt]=v;
    }
    void getrt(int x,int fa){
        siz[x]=1; mxd[x]=0;
        for(int i=hd[x];i;i=nxt[i]){
            int to=poi[i];
            if(to==fa||vis[to]) continue;
            getrt(to,x);
            siz[x]+=siz[to];
            mxd[x]=Max(mxd[x],siz[to]);
        }mxd[x]=Max(mxd[x],sum-siz[x]);
        if(mxd[x]<mxd[rt]) rt=x;
    }
    void getdis(int x,int fa){
        ra[++ra[0]]=dis[x];
        for(int i=hd[x];i;i=nxt[i]){
            int to=poi[i];
            if(to==fa||vis[to]) continue;
            dis[to]=M(dis[x]+val[i]);
            getdis(to,x);
        }
    }
    void calc(int x){
        rb[0]=1;
        for(int i=hd[x];i;i=nxt[i]){
            int to=poi[i];
            if(vis[to]) continue;
            ra[0]=0; dis[to]=val[i];
            getdis(to,x);
            for(int i=ra[0];i;--i)
                ans+=rb[ra[i]?3-ra[i]:0];
            for(int i=ra[0];i;--i) ++rb[ra[i]];
        }rb[0]=rb[1]=rb[2]=0;
    }
    void solve(int x){
        vis[x]=1; calc(x);
        for(int i=hd[x];i;i=nxt[i]){
            int to=poi[i];
            if(vis[to]) continue;
            sum=siz[to]; rt=0; 
            getrt(to,x); solve(rt);
        }
    }
    int gcd(int a,int b){return b?gcd(b,a%b):a;}
    int main(){
        read(n); register int i; int q1,q2,q3;
        for(i=1;i<n;++i){
            read(q1),read(q2),read(q3); q3%=3;
            adde(q1,q2,q3); adde(q2,q1,q3);
        }mxd[rt=0]=n+1; sum=n; getrt(1,0); solve(rt);
        ans=ans*2+n; tot=n*n;
        int g=gcd(ans,tot); ans/=g; tot/=g;
        printf("%d/%d",ans,tot);
        return 0;
    }
  • 相关阅读:
    html总结:背景图片拉伸
    html总结:表格中的文字居中
    html总结:float实现span和input输入框同行
    servlet总结:Servlet基础
    js总结:JavaScript入门
    河北科技创新平台年报系统涉众分析
    确定业务问题的范围-上下文的范围模型
    问题账户需求分析
    Struts2------OGNL表达式
    Struts入门
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/10574544.html
Copyright © 2011-2022 走看看