首页 > 其他 > 详细

codevs1304 拓扑序计数

时间:2015-03-27 21:21:55      阅读:155      评论:0      收藏:0      [点我收藏+]

题目描述                     Description                   

求一颗有根树/树形图的拓扑序个数.

输入描述                 Input Description              

第一行一个n和一个素数P,表示这颗树有n个节点,要求拓扑序个数modP之后的结果.

接下来n-1行,每行有两个数字x和y,表示x是y的父亲.

保证1<=n<=1500000, n<P<2^31,P为质数.

 

 

输出描述                 Output Description              

一行一个数字,为该树形图拓扑序个数modP的结果.

样例输入                 Sample Input              

样例1 4 100000007 1 2 1 3 2 4
样例2 6 100000007 1 2 2 3 1 4 3 5 5 6

样例输出                 Sample Output              

样例1 3
样例2 5

数据范围及提示                 Data Size & Hint              

每个非根节点的儿子个数平均较多,数据量较大,建议c/c++选手才用scanf的读入方式

#include<iostream>
#include<cstring>
#include<cstdio>

using namespace std;

int md;

long long gcd(long long y3)
{
    long long x1 = 1,x2 = 0,y1 = 0,y2 = 1,x3 = md,t1,t2,t3,q;
    while(1)
    {
        if (y3==1) return y2;
        q=x3/y3;
        t1=x1-q*y1,t2=x2-q*y2,t3=x3-q*y3;
        x1 = y1,x2 = y2,x3 = y3;
        y1 = t1,y2 = t2,y3 = t3;
    }
}

long long an[1510000];
//long long bn[1510000];
long long n;
struct edge
{
    int v,next;
}edge[1510000];
int head[1510000],e = 1;
void increase(int u,int v)
{
    edge[e].v = v;
    edge[e].next = head[u];
    head[u] = e++;
}
int cn[1510000];
long long ans[1510000];
bool rd[1510000];

void dfs(int k)
{
    cn[k] = ans[k] = 1;
    for(int t = head[k];t!=0;t = edge[t].next)
    {
        int v = edge[t].v;
        if(!cn[v]) dfs(v);
        cn[k]+=cn[v];
        ans[k] = ans[k]*(gcd(an[cn[v]])+md)%md*ans[v]%md;
    }
    ans[k] = ans[k]*an[cn[k]-1]%md;
}
int Scan()
{
    char ch;
    int a = 0;
    while((ch = getchar())>=47)
    {
        a = 10*a+ch-48;
    }
    return a;
}


int main()
{
    n = Scan(),md = Scan();
    long long i,j,k;
    //an[0] = bn[0] = 1;
    an[0] = 1;
    for(i = 1;i<=n;i++)
    {
        an[i] = an[i-1]*i%md;
        //bn[i] = bn[i-1]*(gcd(i)+md)%md;
    }
    for(i = 1;i<n;i++)
    {
        int a,b;
        a = Scan(),b = Scan();
        rd[b]|=1;
        increase(a,b);
    }
    int fa;
    for(i = 1;i<=n;i++)
        if(!rd[i])
        {
            fa = i;
            break;
        }
    dfs(fa);
    cout<<ans[fa]<<endl;
    return 0;
}

 

codevs1304 拓扑序计数

原文:http://www.cnblogs.com/wos1239/p/4372641.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!