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

uva 11174 - Stand in a Line(逆元+递推)

时间:2014-05-22 13:24:44      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:style   class   c   code   tar   http   

题目连接:uva 11174 - Stand in a Line

题目大意:村子里有n个村名民,现在他们要排成一列,处于对长辈的尊敬,他们不能排在自己父亲的前面,有些人的父亲不一定在村子了。问有多少种列的顺序。

解题思路:【算法竞赛入门经典-训练指南】的例题,主要还用到了欧几里得拓展定理求逆元。

#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;
typedef long long ll;
const int N = 40005;
const ll MOD = 1e9+7;

int n, m;
ll v[N];
vector<int> g[N];

void init () {
    scanf("%d%d", &n, &m);

    memset(v, 0, sizeof(v));
    for (int i = 0; i <= n; i++)
        g[i].clear();

    int a, b;
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &a, &b);
        g[b].push_back(a);
    }
}

ll dfs(int x) {
    if (v[x])
        return v[x];

    for (int i = 0; i < g[x].size(); i++)
        v[x] += dfs(g[x][i]);
    return ++v[x];
}

void gcd (ll a, ll b, ll& x, ll& y, ll& d) {
    if (b == 0) {
        d = a;
        x = 1;
        y = 0;
    } else {
        gcd(b, a%b, y, x, d);
        y -= x*(a/b);
    }
}

int main () {
    int cas;
    scanf("%d", &cas);
    while (cas--) {
        init ();

        ll ans = 1, b = 1;
        for (ll i = 1; i <= n; i++)
            ans = (ans * i) % MOD;

        for (int i = 1; i <= n; i++)
            b = (b * dfs(i)) % MOD;

        ll p, k, d = 1;
        gcd(b, MOD, p, k, d);
        ans = ((ans * p) % MOD + MOD) % MOD;
        printf("%lld\n", ans);
    }
    return 0;
}

uva 11174 - Stand in a Line(逆元+递推),布布扣,bubuko.com

uva 11174 - Stand in a Line(逆元+递推)

标签:style   class   c   code   tar   http   

原文地址:http://blog.csdn.net/keshuai19940722/article/details/26142993

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!