做题目记录
SPOJ INS14F
其实这题还是比较丝播的> <
题意
...很长的题目,zball英语渣QwQ...
构造一些长度为k的正整数数列,数列中的每个数互不相同,且值在[1, n]范围内。
- 要求构造出的数列互不相同,相同的定义是数列上每个位置的数都相同。
- 对于构造出来的任意两个数列,要求这两个数列中必须
有相同的数(不一定要在相同的位置)。 - 求最多可以构造出多少个数列,答案mod 1000000007。
题解
分类讨论> <
对于2k>N,显然通过抽屉原理可知必有两两数组间必有数相等. \(A(n,k)=\frac{n!}{(n-k)!}\)
对于另外一种情况,我们强行构造相等,答案\(k!A(n-1,k-1)\).
膜Stilwell爷.膜RXDoi(RX队爷),膜pi_pyc.
SPOJ似乎不兹瓷读入优化眼泪吧嗒吧嗒掉下来T^T...
CODE
#include <cstdio>
#define foxe(i,f,t) for(int i=f;i<=t;++i)
#define qn 1000000u
#define pn 1000010u
#define modm 1000000007u
typedef unsigned long long ull;
typedef unsigned int ul;
inline void linv(ul* q,ul p,ul m){ q[1]=1; foxe(i,2,p) q[i]=((ull)(m-m/i)*q[m%i])%m; }
ul fac[pn],ifac[pn];
inline ull c(ul n,ul k,ul p){ return (ull)fac[n]*ifac[n-k]%(ull)p;}
void work(){
ul a,b;
scanf("%u%u",&a,&b);
if((b<<1) > a) a=(ul)c(a,b,modm); else a=c(a-1,b-1,modm)*(ull)b%modm;
printf("%u\n",a);
}
int main(){
ul t;
ifac[0]=1;fac[0]=1;fac[1]=1;
linv(ifac,qn,modm);
foxe(i,2,qn) fac[i]=(ull)i*fac[i-1]%modm,ifac[i]=(ull)ifac[i]*ifac[i-1]%modm;
scanf("%u",&t);
while(t--) work();
return 0;
}
692Bytes.
SPOJ INS14H
题意
zball看了半天O O
恩这题就是说在n维空间内,首先只有一个细胞(在原点),细胞每秒分裂一次,分裂出\(2n\)个,分别推到与细胞所在点相邻的那些点每个点一个.每个点都能存下无数的细胞(细胞挤呀挤> <挤呀挤> <),问经过T秒原点有多少细胞(窝萌的n维培养皿是无限大的> <).
多组数据,
<integer>testcases
(for testcases)
<integer>n T<restriction (1<=n<=100) (1<=T<=200)>//n stands for n-dimension, T stands for T seconds
(end for)
输出
(for testcases)
<integer modulo 1000000007(prime)> ans//stands for answer
(end for)
样例
输入
3
1 2
2 3
3 2
输出
2
0
6
题解
其实这题比较丝播T^T我在几个月前写过这题> >没过> >原谅我的s×吧...
首先我们可以建个图> >显然是二分图,网格图都是二分图> >证明可脑补,因为显然是根据曼哈顿距离奇偶性可以分成二分图的
那么可以发现如果T是奇数显然ans=0
T是偶数的情况呢?
这个问题的等价问题就是n维长度为T的从原点出发最终回到原点的路径条数.
考虑对于每一个维度分开处理.每一维移动的相对坐标之和为0,类似于\(1 -1 -1 1\)这样的移动.
我们记f[i][j]为有i维,走了2j步的返回原点路径条数.
f[1][n]=\(2n \choose n\).为什么?考虑在1..2n中选出n个数,\(A_1\dots A_n\),在第\(A_x\)步时我们将坐标-1,否则+1,显然序列与可能的路径一一对应.
现在假设我们处理好了n-1维的情况.我们可得
f[i][j]=\(\sum\limits_{k=0}^{j}{2j\choose 2k}{2k\choose k}f[i-1][j-k]\).为什么?总共操作数2j,其中我们选出2k条来执行在这个新维度上的操作,而对于这个新维度我们可以单独计算路径可能性就是\(2k\choose k\),对于所有可能的k都把数字加起来显然是答案.
CODE
#include <cstdio>
#define fox(i,f,t) for(int i=f;i<t; ++i)
#define foxe(i,f,t) for(int i=f;i<=t;++i)
#define maxn 205
#define maxm 105
#define modm 1000000007
typedef unsigned long long ull;
typedef unsigned int ul;
ul c[maxn+10][maxn+10],u[maxm+10][maxm+10];
inline void work(){
ul a,b;
scanf("%u%u",&a,&b);
a=u[a][b>>1];
if(b&1) printf("0\n"); else printf("%u\n",a);
}
int main(){
c[0][0]=1,c[1][0]=1,c[1][1]=1;
fox(i,2,maxn) foxe(j,0,i) c[i][j]=(c[i-1][j-1]+c[i-1][j])%modm;
fox(i,0,maxm) u[1][i]=c[i<<1][i];
fox(i,2,maxm) fox(j,0,maxm){
int pg=0;
fox(k,j,maxm){
u[i][k]=((ull)c[k<<1][j<<1]*c[pg<<1][pg]%(ull)modm*u[i-1][j]+u[i][k])%modm;
++pg;
}
}
ul t;
scanf("%u",&t);
while(t--) work();
return 0;
}
730Bytes.