您的位置:首页 > 产品设计 > UI/UE

[杂题]CSUOJ1276 Counting Route Sequence

2014-12-10 21:35 204 查看
题目链接

题意:从1号点走到n号点(每条边只能走一次, 两结点间的边数必定为奇数)

问 经过结点不同顺序的方式有多少种(如1->2->3->4和1->3->2->4为两种)

方法数模上1000000007

此题只需先考虑相邻两结点交替的方法数 然后依次递推相乘即可

就是:如从1走到5

只需先考虑2、3交替的方法数:(很明显与边数有关的组合数)

然后类似的考虑3、4交替的方法数

最后全部相乘就可以了

公式是$\displaystyle\prod\limits_{i=1}^n\Bigg({\Large\complement}_{\frac{a_{i+1}-1}{2}+\frac{a_i-1}{2}}^{\frac{a_i-1}{2}}\Bigg)$

$C_n^m$的公式是 $\frac{n!}{m!(n-m)!}$

因为n、m的范围为$10^5$, 所以要进行取模, 因此就要求m!(n-m)!的逆元

要是直接for一遍 再对tmp做ex_gcd 果然TLE。。。

LL tmp=1, ans=1;
for(LL i=min(n, m);i>=1;i--)
{
tmp=(tmp*i)%mod;
ans=(ans*(n+1-i))%mod;
}


所以可以先对$10^5$内的阶乘打个表 预处理一下

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cctype>
#include <cmath>
#include <string>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <map>
typedef long long LL;
typedef long double LD;
const double pi=acos(-1.0);
const double eps=1e-9;
#define INF 0x3f3f3f
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
typedef pair<int, int> PI;
typedef pair<int, PI > PP;
#ifdef _WIN32
#define LLD "%I64d"
#else
#define LLD "%lld"
#endif
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//LL quick(LL a, LL b){LL ans=1;while(b){if(b & 1)ans*=a;a=a*a;b>>=1;}return ans;}
//inline int read(){char ch=' ';int ans=0;while(ch<'0' || ch>'9')ch=getchar();while(ch<='9' && ch>='0'){ans=ans*10+ch-'0';ch=getchar();}return ans;}
inline void print(LL x){printf(LLD, x);puts("");}
//inline void read(LL &ret){char c;int sgn;LL bit=0.1;if(c=getchar(),c==EOF) return ;while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();sgn=(c=='-')?-1:1;ret=(c=='-')?0:(c-'0');while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');if(c==' '||c=='\n'){ ret*=sgn; return ; }while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;ret*=sgn;}

const int mod=1000000007;
int a[100005];
LL JC[200005];
void pre()
{
JC[0]=1;
for(int i=1;i<=200000;i++)
JC[i]=(i*JC[i-1])%mod;
}
void ex_gcd(LL a, LL b, LL &x, LL &y)
{
if(b)
{
ex_gcd(b, a%b, x, y);
LL tmp=x;
x=y;
y=tmp-(a/b)*y;
}
else
{
x=1, y=0;
return ;
}
}
LL C(LL n, LL m)
{
if(n==m || m==0)
return 1;
if(m==1 || m==n-1)
return n;
//    LL tmp=1, ans=1;
//    for(LL i=min(n, m);i>=1;i--)
//    {
//        tmp=(tmp*i)%mod;
//        ans=(ans*(n+1-i))%mod;
//    }
LL x, y;
ex_gcd(JC[m]*JC[n-m], mod, x, y);
return (JC
*x)%mod;
}
LL MOD(LL x)
{
while(x<0)
x+=mod;
return x%mod;
}
int main()
{
pre();
int t;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
for(int i=0;i<n-1;i++)
scanf("%d", &a[i]);
LL ans=1;
for(int i=0;i<n-2;i++)
ans=(ans*C((a[i+1]-1)/2+(a[i]-1)/2, (a[i]-1)/2)%mod)%mod;
print(MOD(ans));
}
return 0;
}


CSUOJ 1276
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: