http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2115

数学的特点在于不断的推导,此题还需要用到

欧拉定理和逆元的相关性质,推荐博客(有部分小错误):http://www.cnblogs.com/vongang/archive/2013/06/04/3117370.html

代码:

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>

#define ll long long
using namespace std;

const ll MOD=1000000007;
const int N=100005;
ll power(ll x,ll y)
{
    ll tmp=1;
    while(y)
    {
        if(y&1)
        tmp=tmp*x%MOD;
        x=x*x%MOD;
        y=y>>1;
    }
    return tmp;
}
int num[N],f[N],sum[N];
queue<int>qt;
int main()
{
    //freopen("data.in","r",stdin);
    int T;
    cin>>T;
    while(T--)
    {
        int n,m;
        cin>>n>>m;
        memset(num,0,sizeof(num));
        memset(sum,0,sizeof(sum));
        memset(f,0,sizeof(f));
        while(!qt.empty()) qt.pop();
        while(m--)
        {
            int a,b;
            cin>>a>>b;
            ++num[b];
            f[a]=b;
        }
        for(int i=1;i<=n;++i)
        if(num[i]==0)
        qt.push(i);

        ll x=1,y=1;
        while(!qt.empty())
        {
            int i=qt.front();qt.pop();
            ++sum[i];
            y=y*sum[i]%MOD;
            sum[f[i]]+=sum[i];
            if((--num[f[i]])==0)
            qt.push(f[i]);
        }
        for(int i=1;i<=n;++i)
        x=x*i%MOD;
        cout<<(x*power(y,MOD-2))%MOD<<endl;
    }
    return 0;
}

  

 

posted on 2013-07-06 16:24  夜->  阅读(258)  评论(0编辑  收藏  举报