【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 ...
随机推荐
- Selenium之WebDriverWait
转自https://blog.csdn.net/duzilonglove/article/details/78455051 Selenium之WebDriverWait用法
- java.sql.SQLException: Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT) for operation '='
查询视图时报错:java.sql.SQLException: Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_ ...
- UNP学习第五章(二)
一.POSIX信号处理 信号:告知某进程发生了某个事件的通知(软中断),通常是异步的. 信号可以:由进程发给另一个进程,由内核发给某个进程. 设置信号处理办法,有三个选择: 1.写一个函数,在信号发生 ...
- JDK 9 发布仅数月,为何在生产环境中却频遭嫌弃?
千呼万唤始出来,在经历了整整一年的跳票之后,Java 9 终于在 9 月 21 日拨开云雾,露出真正的面目.对众多 Java 程序员来说,这一天无疑是一个重大的日子,首先 Java 开发者们再也不用羡 ...
- AcWing 225. 矩阵幂求和 (矩阵快速幂+分治)打卡
题目:https://www.acwing.com/problem/content/227/ 题意:给你n,k,m,然后输入一个n阶矩阵A,让你求 S=A+A^2+A^3.+......+A^k 思 ...
- 3D打印切片软件Cura及CuraEngine原理分析
引言 年初开始进入3D打印行业,受命以Cura为基础,研发一款自主的3D打印切片软件. 自主研发要取其长处,补其不足,首先自然是要搞清楚Cura到底做了什么,读Cura的代码是必需的.我一向都觉得比起 ...
- 老板让我十分钟上手nx-admin
大体流程 参考资料: nx-admin项目地址 首先这里就不讲解vue和vuex之类的基础东西了 有兴趣的可以去官方文档了解.这里根据流程走向大概说说 路由配置 首先找到路由配置,路由配置放在了src ...
- ICO和区块链区别
区块链项目众筹(ICO)浅析 2017-07-25 原创 Fintech科普大使 ICO是区块链初创公司项目融资的重要方式类似于Kickstarter众筹,但有不同之处(具体在下一节详述),可以避开传 ...
- react 中使用 JsBarcode 显示条形码
import React from 'react';import JsBarcode from 'jsbarcode'; export class RefundSheet extends React. ...
- JS-ValidForm:介绍
ylbtech-JS-ValidForm:介绍 1.返回顶部 1. 关于Validform Validform:一行代码搞定整站的表单验证! 1 $(".demoform").Va ...