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

Uva 11174 Stand in a Line

时间:2018-05-24 23:07:40      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:cstring   方案   printf   pac   ==   efi   stand   crt   记忆化   

Stand in a Line Uva 11174

题意:把n个人排成一列,使得没有人排在他父亲的前面,输出方案数MOD 1000000007

思路:《算法竞赛入门经典》P 111

AC代码:

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
using namespace std;
const int N_MAX = 40000 + 20;
const int MOD = 1000000007;
typedef long long ll;
int num[N_MAX];//记忆化搜索以,i为根节点的子树的节点数量
int e_gcd(int a,int b,int &x,int &y) {
    if (b == 0) {
        x = 1; y = 0;
        return a;
    }
    int ans = e_gcd(b,a%b,x,y);
    int temp = x;
    x = y;
    y = temp - a / b*y;
    return ans;
}

int mod_inverse(int a,int m) {
    int x, y;
    e_gcd(a,m,x,y);
    return (m + x%m) % m;
}
int n, m;
vector<int>G[N_MAX];

int dfs(int x) {//寻找以x为根的子树的节点数量
    if (num[x])return num[x];
    for (int i = 0; i < G[x].size();i++) {
        num[x] += dfs(G[x][i]);
    }
    return ++num[x];
}

int main() {
    int t; scanf("%d",&t);
    while (t--) {
        scanf("%d%d",&n,&m);
        memset(num,0,sizeof(num));
        for (int i = 0; i <n; i++)G[i].clear();
        for (int i = 0; i < m;i++) {
            int a, b; scanf("%d%d", &a, &b); a--, b--;
            G[b].push_back(a);
        }
        ll N = 1;
        for (int i = 2; i <= n;i++) {
            N = N*i%MOD;
        }
        ll mul = 1;
        for (int i = 0; i < n;i++) {
            mul = mul*dfs(i)%MOD;
        }
        ll ans = N*mod_inverse(mul, MOD) % MOD;
        printf("%lld\n",ans);
    }
    return 0;
}

 

Uva 11174 Stand in a Line

标签:cstring   方案   printf   pac   ==   efi   stand   crt   记忆化   

原文地址:https://www.cnblogs.com/ZefengYao/p/9085410.html

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