hdoj 4828 卡特兰数取模
Grids
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 93 Accepted Submission(s): 25
他想把1到2N这些数依次放进去。可是为了使格子看起来优美,他想找到使每行每列都递增的方案。只是画了非常久,他发现方案数实在是太多了。度度熊想知道,有多少种放数字的方法能满足上面的条件?
然后T行,每行为一个数N(1<=N<=1000000)表示长方形的大小。
因为数字可能很大,你仅仅须要把最后的结果对1000000007取模就可以。
2
1
3
Case #1:
1
Case #2:
5Hint对于第二组例子。共5种方案,详细方案为:
![]()
通过打表得出前7项分别为1,2,5,14,42,132,429。可知答案为卡特兰数h(n)=C(2n,n)/(n+1)=h(n-1)*(4*n-2)/(n+1)。
一開始採用组合数分解素因子+二分求幂求组合数取模,但是会TLE。组合数求模相关知识http://hi.baidu.com/aekdycoin/item/e051d6616ce60294c5d249d7。渣代码例如以下:
#include <stdio.h>
#include <string>
#include <iostream>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 2000005;
const int n=148955;
bool a[N];//a[]的长度比pr[]的长度长得多
int pr[n];
#define MOD 1000000007
int num;
void Prime2()
{
memset(a, 0, N*sizeof(a[0]));
int i, j;
num = 0;
a[0]=a[1]=1;
for(i = 2; i < N; ++i)
{
if(!(a[i])) pr[num++] = i;
for(j = 0; (j<num && i*pr[j]<N); ++j)
{
a[i*pr[j]] = 1;
if(!(i%pr[j])) break;
}
}
}
int val[n],len;
void calcJC(int n,int id,int flag){
int ans=0,y,p=pr[id];
while(n){
y=n/p;
ans+=y;
n=y;
}
val[id]=val[id]+ans*flag;
}
__int64 extgcd(__int64 a,__int64 b,__int64 &x,__int64 &y)
{
if(b==0)
{
x=1,y=0;
return a;
}
__int64 r=extgcd(b,a%b,x,y);
__int64 t=x;x=y;y=t-a/b*y;
return r;
}
int MPow(int p,int e){
if(e==0)return 1;
else if(e==1)return p;
int t=p,ans=1;
while(e){
if(e&1)ans=(ans*t)%MOD;
t=(t*t)%MOD;
e>>=1;
}
return ans;
}
int main()
{
Prime2();
int txt,l=1,k,i;
__int64 ans,x,y;
scanf("%d",&txt);
while(txt--){
scanf("%d",&k);
memset(val,0,sizeof(val));
for(i=0;pr[i]<=2*k;++i)
calcJC(2*k,i,1);
for(i=0;pr[i]<=k;++i)
calcJC(k,i,-2);
ans=1;
for(i=0;pr[i]<=2*k;++i){
// if(val[i]>0)printf("%d^%d ",pr[i],val[i]);
ans=(ans*MPow(pr[i],val[i]))%MOD;
}
extgcd(k+1,MOD,x,y);
x=(x+MOD)%MOD;
ans=(ans*x)%MOD;
printf("%I64d\n",ans);
}
return 0;
}
无奈,看到n范围不是非常大,直接打表吧、、、
#include <stdio.h>
#include <string>
#include <iostream>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
#define MOD 1000000007
const int N = 1000001;
int a[N];
__int64 extgcd(__int64 a,__int64 b,__int64 &x,__int64 &y)
{
if(b==0)
{
x=1,y=0;
return a;
}
__int64 r=extgcd(b,a%b,x,y);
__int64 t=x;x=y;y=t-a/b*y;
return r;
}
void calcCATALAN(int n){
__int64 x,y;
a[1]=1;
int i;
for(i=2;i<n;++i){
x=a[i-1];
a[i]=(x*(4*i-2))%MOD;
extgcd(i+1,MOD,x,y);
x=(x+MOD)%MOD;
a[i]=(a[i]*x)%MOD;
}
}
int main()
{
calcCATALAN(N);
int txt,l=1,k;
scanf("%d",&txt);
while(txt--){
scanf("%d",&k);
printf("Case #%d:\n",l++);
printf("%d\n",a[k]);
}
return 0;
}
hdoj 4828 卡特兰数取模的更多相关文章
- HDU-4828 卡特兰数+带模除法
题意:给定2行n列的长方形,然后把1—2*n的数字填进方格内,保证每一行,每一列都是递增序列,求有几种放置方法,对1000000007取余: 思路:本来想用组合数找规律,但是找不出来,搜题解是卡特兰数 ...
- uva 10692 Huge Mods 超大数取模
vjudge上题目链接:Huge Mods 附上截图: 题意不难理解,因为指数的范围太大,所以我就想是不是需要用求幂大法: AB % C = AB % phi(C) + phi(C) % C ( B ...
- bjfu1238 卡特兰数取余
题目就是指定n,求卡特兰数Ca(n)%m.求卡特兰数有递推公式.通项公式和近似公式三种,因为要取余,所以近似公式直接无法使用,递推公式我简单试了一下,TLE.所以只能从通项公式入手. Ca(n) = ...
- HDU 4828 (卡特兰数+逆)
HDU 4828 Grids 思路:能够转化为卡特兰数,先把前n个人标为0.后n个人标为1.然后去全排列,全排列的数列.假设每一个1的前面相应的0大于等于1,那么就是满足的序列,假设把0看成入栈,1看 ...
- HOJ 13101 The Triangle Division of the Convex Polygon(数论求卡特兰数(模不为素数))
The Triangle Division of the Convex Polygon 题意:求 n 凸多边形可以有多少种方法分解成不相交的三角形,最后值模 m. 思路:卡特兰数的例子,只是模 m 让 ...
- HDU 4828 (卡特兰数+逆元)
HDU 4828 Grids 思路:能够转化为卡特兰数,先把前n个人标为0,后n个人标为1.然后去全排列,全排列的数列,假设每一个1的前面相应的0大于等于1,那么就是满足的序列.假设把0看成入栈,1看 ...
- Fibonacci数列对任何数取模都是一个周期数列
题目是要求出斐波那契数列n项对一个正整数取模,那么可以把斐波那契数列取模后得到的数列周期求出来. 比如下面一个题目:求出f[n]的后4位,先求出数列对10000取模的周期,然后再查找即可. #incl ...
- 【Gym 100947E】Qwerty78 Trip(组合数取模/费马小定理)
从(1,1)到(n,m),每次向右或向下走一步,,不能经过(x,y),求走的方案数取模.可以经过(x,y)则相当于m+n步里面选n步必须向下走,方案数为 C((m−1)+(n−1),n−1) 再考虑其 ...
- HPU 1471:又是斐波那契数列??(大数取模)
1471: 又是斐波那契数列?? 时间限制: 1 Sec 内存限制: 128 MB 提交: 278 解决: 27 统计 题目描述 大家都知道斐波那契数列吧?斐波那契数列的定义是这样的: f0 = 0; ...
随机推荐
- 了解CSS核心精髓(一)
CSS 1.css外联 正确写法:<link rel="stylesheet" href="css/style.css" /> <style ...
- 如何用jquery+json来写页面
以下是json数据表: [ { "p" : "银川市", "c" : [{"c1":"兴庆区"},{ ...
- 【LeetCode】Binary Tree Level Order Traversal(二叉树的层次遍历)
这道题是LeetCode里的第102道题. 题目要求: 给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 例如: 给定二叉树: [3,9,20,null,null,15 ...
- ZOJ-3953 Intervals,t
Intervals 题意:给出n个区间,求最少删除多少个区间使得任意三个区间都不相交. 思路:按区间左端点排序,每次选取r最大的两个与当前比较,如果能放更新r,否则删除r最大的.关键就在怎么删除r最大 ...
- 九度oj 题目1372:最大子向量和(连续子数组的最大和)
题目描述: HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天JOBDU测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但 ...
- kb-07线段树--11--区间多重该值多种查询
/* lazy思想的运用,因为查询多种,如果全记录就太繁了,lazy就是如果该区间的每一个叶子的状态都相同就不用深入下去该值,只要暂时标记下,查询的时候也不用下去,直接计算: */ #include& ...
- 计算机、程序和java概述
1.1 计算机.程序和java概述计算机包括硬件(hardware)软件(software)两部分.硬件包括计算机中看得见的物理部分,软件提供看不见的指令,指令控制硬件并且使得硬件完成特定的任务.一台 ...
- python语言基础问题汇总
问题汇总 问题分类 怎么在一个python脚本里调用另一个python脚本 把两个脚本filea.py 和 fileb.py 放在同一个目录下,然后在filea.py的开头写: import file ...
- hdu 4400 离散化+二分+BFS(暴搜剪枝还超时的时候可以借鉴一下)
Mines Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- UVa11424 GCD - Extreme (I)
直接两重循环O(n^2)算gcd……未免太耗时 枚举因数a和a的倍数n,考虑gcd(i,n)==a的i数量(i<=n) 由于gcd(i,n)==a等价于gcd(i/a,n/a)==1,所以满足g ...