HDU 4373 Mysterious For(Lucas定理、中国剩余定理)
来源:互联网 发布:structure软件 编辑:程序博客网 时间:2024/04/28 09:47
题目链接:
HDU 4373 Mysterious For
题意:
定义两种循环:
会有
分析:
首先我们考虑第一种循环下面跟
- 对于第一层循环,循环到
i ,显然有f1(i)=1总的循环次数是:∑f1(i)=n=C1n - 对于第二层循环,因为第二层循环属于第二种循环,想要循环到
i ,那么相应的第一层循环就要≤i ,也就是f2(i)=∑j≤if1(j)=i总的循环次数是:∑f2(i)=(n+1)∗n2=C2n+1 - 对于第三层循环,同理可得:
f3(i)=∑j≤if2(i)=(i+1)∗i2总的循环次数是:∑f3(i)=∑12∗(i2+i)=(n+2)∗(n+1)∗(n)6=C3n+2 - …
- 可以发现对于第
k 层循环总的循环次数是Ckn+k−1
接着我们需要计算
令
则有:
因为
利用中国剩余定理求解同余方程。
我们定义:
那么答案就是:
最后在根据乘法原理易知每段求得的答案需要累乘。
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <climits>#include <cmath>#include <ctime>#include <cassert>#define IOS ios_base::sync_with_stdio(0); cin.tie(0);using namespace std;typedef long long ll;const int mod1 = 97;const int mod2 = 3761599;const ll MOD = 364875103;const int MAX_M = 100010;ll fac1[mod1 + 10], fac2[mod2 + 10], e1, e2;ll quick_pow(ll a, ll b, ll mod){ ll res = 1, tmp = a; while(b) { if(b & 1) res = res * tmp % mod; tmp = tmp * tmp % mod; b >>= 1; } return res;}void init() { fac1[0] = fac2[0] = 1; for(int i = 1; i < mod1; ++i) { fac1[i] = fac1[i - 1] * i % mod1; } for(int i = 1; i < mod2; ++i) { fac2[i] = fac2[i - 1] * i % mod2; } e1 = quick_pow(mod2, mod1 - 2, mod1) * mod2; e2 = quick_pow(mod1, mod2 - 2, mod2) * mod1;}ll ex_gcd(ll a, ll b, ll& x, ll& y) { if(b == 0) { x = 1, y = 0; return a; } ll r = ex_gcd(b, a % b, y, x); y -= a / b * x; return r;}ll inv(ll a, ll n){ ll x, y; ll d = ex_gcd(a, n, x, y); if(d == 1) return (x % n + n) % n; else return 0;}ll C(int n, int m, int id, int mod){ if(m > n) return 0; ll a, b, c; if(id == 1) { a = fac1[n], b = fac1[n - m], c = fac1[m]; } else { a = fac2[n], b = fac2[n - m], c = fac2[m]; } //return a * inv(b * c % mod, mod) % mod; //也可以用扩展欧几里德求逆元 return a * quick_pow(b * c % mod, mod - 2, mod) % mod;}ll Lucas(int n, int m, ll mod, int id){ if(m == 0) return 1; return C(n % mod, m % mod, id, mod) * Lucas(n / mod, m / mod, mod, id) % mod; }int main(){ init(); int T, n, m, num, data[30], cases = 0; scanf("%d", &T); while(T--) { scanf("%d%d%d", &n, &m, &num); for(int i = 0; i < num; ++i) { scanf ("%d", &data[i]); } data[num++] = m; ll ans = 1; for(int i = 1; i < num; ++i) { int k = data[i] - data[i - 1]; ll t1 = Lucas(n + k - 1, k, mod1, 1) * e1 % MOD; ll t2 = Lucas(n + k - 1, k, mod2, 2) * e2 % MOD; ans = ans * (t1 + t2) % MOD; } printf("Case #%d: %lld\n", ++cases, ans); } return 0;}
0 0
- HDU 4373 Mysterious For(Lucas 定理 + 中国剩余定理)
- HDU 4373 Mysterious For(Lucas定理、中国剩余定理)
- 【HDU 4373】【Lucas定理+中国剩余定理】 Mysterious For
- hdu 4373 Mysterious For 【Lucas定理】
- hdu-5446(中国剩余定理+lucas)
- HDU 5446 lucas定理 + 中国剩余定理
- HDU 5446 Unknown Treasure(Lucas定理+中国剩余定理)
- hdu 5446 Unknown Treasure(Lucas定理+中国剩余定理)
- HDU 5446 Unknown Treasure(Lucas定理+中国剩余定理)
- hdu 5446 Unknown Treasure (Lucas定理+中国剩余定理)
- HDU 5446 (中国剩余定理 Lucas)
- hdu 5446 Unknown Treasure(lucas+中国剩余定理)
- Hdu 5446 Unknown Treasure(Lucas+中国剩余定理)
- HDU 5446 Unknown Treasure(lucas+中国剩余定理 / CRT)
- hdu 5446 Unknown Treasure(lucas定理+中国剩余定理)
- HDU 5446 Unknown Treasure Lucas定理+中国剩余定理
- hdu 5446 lucas + 中国剩余定理 + 快速乘 (快速乘板子,中国剩余定理板子,lucas最新板子)
- hdu4373 Mysterious For(剩余定理+Lucus定理)
- 动态规划
- 蛇形填数问题
- Linux下python调试
- UIView指定角为圆角
- Android Studio里的Gradle的初探索
- HDU 4373 Mysterious For(Lucas定理、中国剩余定理)
- tar 命令详解
- Irrlicht引擎学习笔记(15)--LightManager
- Sum of Two Integers
- [编程之美]中国象棋将帅问题
- 【MyBatis框架】mybatis逆向工程自动生成代码
- Android四大基本组件介绍以及四大组件的生命周期
- 常见SOC启动流程分析
- 一种新型内存SCM(Storage Class Memory)的简单介绍