【NOI2019模拟2019.6.29】组合数(Lucas定理、数位dp)
Description:
p<=10且p是质数,n<=7,l,r<=1e18
题解:
Lucas定理:
\(C_{n}^m=C_{n~mod~p}^{m~mod~p}*C_{n/p}^{m/p}\)
若把\(n,m\)在p进制下分解,那么就是\(\prod C_{n[i]}^{m[i]}\)。
对于\(∈[l,r]\)的限制先容斥为\(<=r\)。
考虑从低位到高位的数位dp,设\(f[i][S][j]\)表示做了前i位,S[i]第i个数选的数是<=还是>,进了j位,的系数和。
转移的话可以枚举每个数这一位选了什么,当然就是枚举<=或者>,当然这样还是很慢。
不妨再用一个dp来转移,设\(g[i][S][j]\)表示考虑了前i个数,现在的状压态是S,这一位的和是j,初值是\(g[0][S][j]=f[i][S][j]\)。
那么总时间复杂度大概是\(O(2^n*log_p^m*2^n*(pn)^2)\)
反正跑得过。
Code:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i < B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;
int jx[11][11];
int n, p;
ll m, l[101], r[11], a[11];
int b[101], b0, c[11][101], c0[11];
int a2[10];
int ans;
int f[2][1 << 7][8], o;
int g[2][1 << 7][60], o2;
#define mem(a) memset(a, 0, sizeof a)
void dp(int xs) {
mem(c);
fo(i, 1, n) {
ll v = a[i];
c0[i] = 0;
for(; v > 0; v /= p) c[i][++ c0[i]] = v % p;
}
mem(f); f[o][0][0] = 1;
fo(i, 1, b0) {
mem(f[!o]);
mem(g);
ff(j, 0, a2[n]) fo(k, 0, n - 1) g[o2][j][k] = f[o][j][k];
fo(j, 1, n) {
mem(g[!o2]);
ff(s, 0, a2[n]) fo(k, 0, 48) if(g[o2][s][k]) {
g[o2][s][k] %= p;
int s2 = s & (a2[n] - 1 - a2[j - 1]);
int ns = s2;
int l = 0, r = c[j][i] - 1;
fo(u, l, r) g[!o2][ns][k + u] += g[o2][s][k];
ns = s;
l = r = c[j][i];
g[!o2][ns][k + l] += g[o2][s][k];
ns = s2 + a2[j - 1];
l = c[j][i] + 1, r = p - 1;
fo(u, l, r) g[!o2][ns][k + u] += g[o2][s][k];
}
o2 = !o2;
}
ff(s, 0, a2[n]) fo(k, 0, 48) {
f[!o][s][k / p] += g[o2][s][k] * jx[b[i]][k % p];
}
ff(s, 0, a2[n]) fo(k, 0, p - 1) f[!o][s][k] %= p;
o = !o;
}
ff(s, 0, a2[n]) {
int ky = 1;
fo(j, 1, n) if((s >> (j - 1) & 1) && c0[j] <= b0) { ky = 0; break;}
if(ky) ans = (ans + f[o][s][0] * xs) % p;
}
}
void dg(int x, int xs) {
if(x > n) {
dp(xs);
return;
}
a[x] = l[x] - 1; dg(x + 1, -xs);
a[x] = r[x]; dg(x + 1, xs);
}
int main() {
freopen("combination.in", "r", stdin);
freopen("combination.out", "w", stdout);
fo(i, 0, 7) a2[i] = 1 << i;
scanf("%d %lld %d", &n, &m, &p);
fo(i, 0, 10) {
jx[i][0] = 1;
fo(j, 1, i) jx[i][j] = (jx[i - 1][j - 1] + jx[i - 1][j]) % p;
}
fo(i, 1, n) scanf("%lld %lld", &l[i], &r[i]);
for(; m; m /= p) b[++ b0] = m % p;
dg(1, 1);
ans = (ans % p + p) % p;
pp("%d\n", ans);
}
【NOI2019模拟2019.6.29】组合数(Lucas定理、数位dp)的更多相关文章
- uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT)
uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT) uoj 题目描述自己看去吧( 题解时间 首先看到 $ p $ 这么小还是质数,第一时间想到 $ lucas $ 定理. 注意 ...
- BZOJ4737 组合数问题 【Lucas定理 + 数位dp】
题目 组合数C(n,m)表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3)三个物品中选择两个物品可以有( 1,2),(1,3),(2,3)这三种选择方法.根据组合数的定义,我们可以给 ...
- bzoj 1902: Zju2116 Christopher lucas定理 && 数位DP
1902: Zju2116 Christopher Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 172 Solved: 67[Submit][Stat ...
- [BZOJ4591][SHOI2015]超能粒子炮·改(Lucas定理+数位DP)
大组合数取模可以想到Lucas,考虑Lucas的意义,实际上是把数看成P进制计算. 于是问题变成求1~k的所有2333进制数上每一位数的组合数之积. 数位DP,f[i][0/1]表示从高到低第i位,这 ...
- [JZOJ6241]【NOI2019模拟2019.6.29】字符串【数据结构】【字符串】
Description 给出一个长为n的字符串\(S\)和一个长为n的序列\(a\) 定义一个函数\(f(l,r)\)表示子串\(S[l..r]\)的任意两个后缀的最长公共前缀的最大值. 现在有q组询 ...
- 【NOI2019模拟2019.6.29】字符串(SA|SAM+主席树)
Description: 1<=n<=5e4 题解: 考虑\(f\)这个东西应该是怎样算的? 不妨建出SA,然后按height从大到小启发式合并,显然只有相邻的才可能成为最优答案.这样的只 ...
- 【(好题)组合数+Lucas定理+公式递推(lowbit+滚动数组)+打表找规律】2017多校训练七 HDU 6129 Just do it
http://acm.hdu.edu.cn/showproblem.php?pid=6129 [题意] 对于一个长度为n的序列a,我们可以计算b[i]=a1^a2^......^ai,这样得到序列b ...
- 【BZOJ-4591】超能粒子炮·改 数论 + 组合数 + Lucas定理
4591: [Shoi2015]超能粒子炮·改 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 95 Solved: 33[Submit][Statu ...
- [Swust OJ 247]--皇帝的新衣(组合数+Lucas定理)
题目链接:http://acm.swust.edu.cn/problem/0247/ Time limit(ms): 1000 Memory limit(kb): 65535 Descriptio ...
随机推荐
- python--生成器、三元表达式、列表解析、生成器表达式
补充: 在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作 func_dic={} def make_dic(key): def deco(func): func_dic[ ...
- Linux系统之-常用命令及技巧
一. 通用命令:1.date :print or set the system date and time2. stty -a: 可以查看或者打印控制字符(Ctrl-C, Ctrl-D, Ctrl-Z ...
- LR快捷键
record optioning:录制选项——ctrl+f7 runtime setting : 运行时设置——F4 运行脚本——F5 参数列表:ctrl+L 注释:ctrl+shift+c 选中后 ...
- 【React】react&&redux调试工具
一.React调试工具 1.安装 react-developer-tools,在chrome应用商店进行下载,因为网络限制原因,我们可以使用火狐浏览器进行安装下载 a.打开火狐浏览器的附加组件 b.搜 ...
- ztree 数组和树结构互转算法
//树转化为数组transformToArrayFormat: function (setting, nodes) { if (!nodes) return []; var childKey = se ...
- VC的小工具查询exe的依赖
查看程序或动态库所依赖的动态库 dumpbin /dependents abc.exe 查看动态库的输出函数 dumpbin /exports abc.dll
- C#基本语法1 ----> 实例
| 版权声明:本文为博主原创文章,未经博主允许不得转载. ///////////////////////////////////////////////////////////////////// ...
- JPA单向和双向关系
单向关系 @JoinColumn 双向关系 @OneToMany @ManyToMany mappedBy
- c# dotNetBar symbol属性代码动态设置方法
C#: button.Symbol = "\uf060"; VB: button.Symbol = ChrW("&Hf060") Since we in ...
- connect failed: 127.0.0.1#953: connection refused
Problem1 : root@jeremy-VirtualBox:/etc/bind# /etc/init.d/bind9 restart * Stopping domain name servic ...