做题目记录

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.

posted @ 2015-08-07 00:23  zball  阅读(226)  评论(0编辑  收藏  举报