BZOJ 4403: 序列统计 (组合数 Lucas 数论推导)
来源:互联网 发布:orcle数据库优化方法 编辑:程序博客网 时间:2024/05/16 01:13
BZOJ 4403: 序列统计
Time Limit: 3 Sec Memory Limit: 128 MB
Description
给定三个正整数N、L和R,统计长度在1到N之间,元素大小都在L到R之间的单调不降序列的数量。输出答案对10^6+3取模的结果。
Input
输入第一行包含一个整数T,表示数据组数。
第2到第T+1行每行包含三个整数N、L和R,N、L和R的意义如题所述。
1≤N,L,R≤10^9,1≤T≤100,输入数据保证L≤R。
Output
输出包含T行,每行有一个数字,表示你所求出的答案对10^6+3取模的结果。
Sample Input
2
1 4 5
2 4 5
Sample Output
2
5
思路:
一道标准的排列组合题目,不过思维很是巧妙,辣鸡的我困扰了许久。
这道题目我们很容易想到一位一位的去考虑,相邻位数之间的递推关系不难发现,但让人崩溃的是1e9的数据规模,递推肯定挂得死死的。虽然无奈但是我们还是确定了思路,一个式子解决问题!
然后。。。额,活生生被搞成了一道数学题。
进过多次尝试后,我绝望地发现,好像并没有什么公式或方法可以直接解决这一问题,那么还是只能对于1~n中的一个i进行分析。我们发现无论我们选出来哪一些数,针对于这些数,有且只有一种排列方式让它满足单调不降(相同数之间交换认为是同一种)。
所以就成了组合问题。如果是单纯的C(m,i),并不包含一种元素可以多选的情况,那如果我们每个元素都取i个呢?->C(m*i,i)显然也是有问题的。eg:2 4 5这一组数据,本来是(4 5)只有4,5 4,4 5,5,现在变成了(4 4 5 5)有4,4 4,5 4,5 4,5 4,5 5,5。为什么呢?因为我们的组合数把两个4,当做了不同的两个数,就多了很多重复的情况。所以说如果我们要添加元素的话,只能增加有数字重复的状态,而不能增加原有的状态。那么我们考虑不去添加数,而是去添加一些符号,来表示这些重复的数字。eg:还是2 4 5这一组数据,我们添加一个+号,来表示它是某个数后边第一个和它相同的数, 4,+ 就代表4,4 ; 5,+就代表5,5;那么我们就有了三个元素(4 5 +);方案就有4,5;4,+;5,+三种,这种方法既解决了有数字重复的情况,又不影响没有数字的情况。
找到了解决方法,做普遍推广,对于i位数,我们添加i-1个符号(最多有i个重复数字),所以方案数就是C(m+i-1,i)。
现在只剩下sigma的问题了,(当然不能for一遍sum)。因为C(m,n)=C(m-1,n)+C(m-1,n-1),在m个东西中取n个,可以分成两类,【(1)不取第一个,那么就是在剩下的m-1个里面取n个。(2)取了第一个,那么就是在剩下的m-1个里面取n-1个。】
我们要求的答案就是,C(m+n-1,n)+C(m+n-2,n-1)+…+C(m+1,2)+C(m,1);
如果我们在式子的末尾添上一个C(m,0);
原式就变成了C(m+n-1,n)+C(m+n-2,n-1)+…+C(m+1,2)+C(m,1)+C(m,0);
因为C(m,1)+C(m,0)=C(m+1,1);
所以原式=C(m+n-1,n)+C(m+n-2,n-1)+…+C(m+1,2)+C(m+1,1);
又因为C(m+1,1)+C(m+1,2)=C(m+2,2);
所以原式=C(m+n-1,n)+C(m+n-2,n-1)+…+C(m+2,2);
…最终ans就是C(m+n,n);
因为我们加上了一个C(m,0);所以最后减掉一个1。
我们求C(m+n,n) - 1!完美!!
然后就是Lucas,逆元求组合数了。
注意一下,因为我们最后要-1,ans可能为负,所以我们做一个处理 ( ans ) % mod + mod ) % mod 。
如果下面的操作还有不懂的话请转至组合数
#include <cstdio>#include <iostream>#define LL long longusing namespace std;const LL mod = 1e6 + 3;LL mub[mod+10];LL x, y;void init(){//初始化阶乘..超过mod mub[0] = 1;//注意细节 for(int i=1; i<=mod+5; i++){ mub[i] = mub[i-1] * i % mod; }}LL exgcd(LL a, LL b, LL &x, LL &y){//扩展欧几里得求逆元 if(a == 0 && b == 0) return -1; if(b == 0){ x = 1; y = 0; return a; } LL d = exgcd(b, a % b, y, x); y -= a / b * x; return d;}LL mod_reverse(LL a, LL n){ LL d = exgcd(a, n, x, y); if(d == 1) return ( x % n + n ) % n; else return -1;}LL solve(LL a, LL b){ if(a > b) return 0;// LL nn = mod_reverse((mub[a] * mub[(b + mod - a) % mod]) % mod, mod); return mub[b] * nn % mod;}void to_solve(LL a, LL b){//Lucas if(b < mod){ solve(a, b); return; } printf("%lld\n", ( (solve(a/mod, b/mod) * solve(a%mod, b%mod) - 1 ) % mod + mod ) % mod );//}int main(){ int T; scanf("%d", &T); init(); while ( T-- ){ LL n, l ,r; scanf("%lld%lld%lld", &n, &l, &r); LL m = r - l + 1; if(m + n < mod){ printf("%lld\n", ( ( solve(n, m+n) - 1 ) % mod + mod ) % mod );// } else to_solve(n, m+n); } return 0;}
- BZOJ 4403: 序列统计 (组合数 Lucas 数论推导)
- BZOJ-4403 序列统计 组合数学 + Lucas定理
- bzoj 4403: 序列统计 lucas定理+组合数学
- BZOJ 4403: 序列统计 Lucas
- 【BZOJ】4403 序列统计 Lucas
- 【BZOJ4403】【lucas】【组合数】序列统计 题解
- 4403: 序列统计 组合数学+Lucas定理
- BZOJ 4403 序列统计 Lucas定理
- BZOJ 4403: 序列统计|Lucas定理
- [BZOJ 4403]序列统计:Lucas定理
- [BZOJ]4403: 序列统计 Lucas定理
- 【BZOJ 4403】【推公式+Lucas定理】 序列统计
- [Lucas 原理+逆元]BZOJ 4403——序列统计
- 组合数 (Lucas)
- BZOJ 4403:浅谈Lucas定理应用及组合数建模
- Bzoj4403序列统计:Lucas初探,组合数学
- bzoj4403 序列统计 ( 组合数学 + lucas )
- [组合数学] BZOJ 4403 序列统计
- View.ViewTreeObserver介绍
- Intellij IDEA自动生成serialVersionUID配置
- Linux配置Java及Tomcat
- :未来5-10年,NLP将走向成熟
- ArcGIS Engine实现图层间空间选择的优化策略
- BZOJ 4403: 序列统计 (组合数 Lucas 数论推导)
- OpenCV 造轮子(一) salt and pepper噪声函数
- 《深入理解计算机系统》 图7-9 重定位算法理解
- 修改数据类型+增加列+修改列名+设置主键+设置键值默认值+sys_guid函数
- 当你的深度学习模型走进死胡同,问问自己这5个问题
- 请慎用javascript:void(0),尤其是在坑爹的IE6中
- Q109:用PBRT渲染Blender导出的模型
- Linux下添加Tomcat为系统服务
- 欢迎使用CSDN-markdown编辑器