UVa 11174 - Stand in a Line

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;

}

  

 

你可能感兴趣的:(uva)