我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件:
(1)它是从1到2n共2n个整数的一个排列{ai};
(2)所有的奇数项满足a1<a3<…<a2n-1,所有的偶数项满足a2<a4<…<a2n;
(3)任意相邻的两项a2i-1与a2i(1≤i≤n)满足奇数项小于偶数项,即:a2i-1<a2i。
现在的任务是:对于给定的n,请求出有多少个不同的长度为2n的有趣的数列。因为最后的答案可能很大,所以只要求输出答案 mod P的值。
标签:
Aha!这题我突然灵光一现就想到Catalan数……就是按顺序安排1~2n这些数(以满足前两个条件)……分配到奇数位置上的必须比偶数位置上的多(要不就不满足第三个条件了)
Catalan数可以用C(n,2n)/(n+1)直接求
但是这题P不保证是质数感觉很捉急啊= =不会捉啊……然后我也没想到50分的DP,果断滚粗了啊sad QAQ
Orz zyf & 盾爷,搬运题解:
假设现在我对于数字 i ,要把他的 j 次方加到答案中去,若k是 i 的一个质因子,那么我只要把任务交给k和i/k就可以了,因为$i^j=k^j*(\frac{i}{k})^j$,轮到算$k$或者$\frac{i}{k}$的时候只要把他的指数+上 j 即可,如果 i 是质数,直接加答案即可,因为最后的答案为整数,那么必定i的指数是正数。
1 /************************************************************** 2 Problem: 1485 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:316 ms 7 Memory:24708 kb 8 ****************************************************************/ 9 10 //BZOJ 1485 11 #include<vector> 12 #include<cstdio> 13 #include<cstdlib> 14 #include<cstring> 15 #include<iostream> 16 #include<algorithm> 17 #define rep(i,n) for(int i=0;i<n;++i) 18 #define F(i,j,n) for(int i=j;i<=n;++i) 19 #define D(i,j,n) for(int i=j;i>=n;--i) 20 using namespace std; 21 22 int getint(){ 23 int v=0,sign=1; char ch=getchar(); 24 while(ch<‘0‘||ch>‘9‘) {if (ch==‘-‘) sign=-1; ch=getchar();} 25 while(ch>=‘0‘&&ch<=‘9‘) {v=v*10+ch-‘0‘; ch=getchar();} 26 return v*sign; 27 } 28 typedef long long LL; 29 const int N=2000010,INF=~0u>>2; 30 /*******************tamplate********************/ 31 int n,tot,MOD,p[N],v[N],b[N]; 32 LL ans=1; 33 inline LL Pow_mod(LL a,LL b){ 34 LL r=1; 35 for(;b;b>>=1,a=a*a%MOD) if (b&1) r=r*a%MOD; 36 return r; 37 } 38 int main(){ 39 #ifndef ONLINE_JUDGE 40 // freopen("input.txt","r",stdin); 41 // freopen("output.txt","w",stdout); 42 #endif 43 n=getint(); MOD=getint(); 44 F(i,2,n<<1){ 45 if (!v[i]) p[++tot]=i; 46 F(j,1,tot){ 47 if (i*p[j]>2*n) break; 48 v[i*p[j]]=p[j]; 49 if (i%p[j]==0) break; 50 } 51 } 52 //ans=(n+2)*(n+3)*...*(n*2) /(2*3*4*...*n); 53 F(i,2,n) b[i]=-1; 54 F(i,n+2,n<<1) b[i]=1; 55 D(i,n<<1,2) 56 if (!v[i]) ans=ans*Pow_mod(i,b[i])%MOD; 57 else b[v[i]]+=b[i],b[i/v[i]]+=b[i]; 58 printf("%lld\n",ans); 59 return 0; 60 }
我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件:
(1)它是从1到2n共2n个整数的一个排列{ai};
(2)所有的奇数项满足a1<a3<…<a2n-1,所有的偶数项满足a2<a4<…<a2n;
(3)任意相邻的两项a2i-1与a2i(1≤i≤n)满足奇数项小于偶数项,即:a2i-1<a2i。
现在的任务是:对于给定的n,请求出有多少个不同的长度为2n的有趣的数列。因为最后的答案可能很大,所以只要求输出答案 mod P的值。
输入文件只包含用空格隔开的两个整数n和P。输入数据保证,50%的数据满足n≤1000,100%的数据满足n≤1000000且P≤1000000000。
仅含一个整数,表示不同的长度为2n的有趣的数列个数mod P的值。
标签:
原文地址:http://www.cnblogs.com/Tunix/p/4436046.html