• bzoj2152: 聪聪可可


    这题一眼题就是树形DP了,前两天看完,结果因为高烧+流感写不动,今天切了。

    mod数极小,那么f[i][j]表示以i为根节点的子树中,长度%3==j的链的个数。

    答案就是这一个子节点乘以前面的子节点的对应值,用根累计。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    struct node
    {
        int x,y,d,next;
    }a[41000];int len,last[21000];
    void ins(int x,int y,int d)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=last[x];last[x]=len;
    }
    
    int A,B,f[21000][3];
    void dfs(int x,int fa)
    {
        //printf("%d
    ",x);
        f[x][0]++;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fa)
            {
                int d=a[k].d;
                dfs(y,x);
                A+=f[x][0]*f[y][(3-d)%3];//(这一位+d)%3==0
                A+=f[x][1]*f[y][(5-d)%3];
                A+=f[x][2]*f[y][(4-d)%3];
                
                f[x][(0+d)%3]+=f[y][0];
                f[x][(1+d)%3]+=f[y][1];
                f[x][(2+d)%3]+=f[y][2];
            }    
        }
    }
    
    int gcd(int A,int B)
    {
        if(A==0)return B;
        return gcd(B%A,A);
    }
    int main()
    {
        int n,x,y,w;
        scanf("%d",&n);
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%d",&x,&y,&w);w%=3;
            ins(x,y,w);ins(y,x,w);
        }
        
        A=0,B=n*n;
        dfs(1,0);A=A*2+n;
        //printf("%d
    ",A);
        int G=gcd(A,B);
        printf("%d/%d
    ",A/G,B/G);
        return 0;
    }
  • 相关阅读:
    python基本数据类型之整型和浮点型
    Java学习路线
    Linux学习笔记之VIM
    Java基础之流程控制
    Linux学习笔记之Shell
    Java基础之数据类型
    论文提交说明
    IDEA安装教程
    Link summary for writing papers
    1 类基础知识
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8320630.html
Copyright © 2020-2023  润新知