[BZOJ4818][SDOI2017]序列计数(DP+容斥原理+矩乘)
来源:互联网 发布:全看网软件下载 编辑:程序博客网 时间:2024/05/29 12:29
1、大意做法
首先发现,
2、预处理
3、建立朴素DP
设
可以推出
边界为
最后结果为
4、矩阵优化
可以发现,上面的朴素
这里考虑构建
矩阵
矩阵
矩阵
矩阵
然后进行矩阵乘方:
最后结果即为
以上操作注意取模。
代码:
#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 105, CYX = 20170408, M = 2e7 + 5;struct cyx { int m, n, v[N][N]; cyx() {} cyx(int _m, int _n) : m(_m), n(_n) {memset(v, 0, sizeof(v));} friend inline cyx operator * (cyx a, cyx b) { cyx res = cyx(a.m, b.n); int i, j, k; for (i = 1; i <= res.m; i++) for (j = 1; j <= res.n; j++) for (k = 1; k <= a.n; k++) res.v[i][j] = (res.v[i][j] + 1ll * a.v[i][k] * b.v[k][j] % CYX) % CYX; return res; } friend inline cyx operator ^ (cyx a, int b) { cyx c = a, res = cyx(a.m, a.n); int i, j; for (i = 1; i <= res.m; i++) res.v[i][i] = 1; while (b) { if (b & 1) res = res * c; c = c * c; b >>= 1; } return res; }} P, Q, V, W;int n0, m0, p0, cnt[N], cnt0[N];bool prime[M];inline int read() { int res = 0; bool bo = 0; char c; while (((c = getchar()) < '0' || c > '9') && c != '-'); if (c == '-') bo = 1; else res = c - 48; while ((c = getchar()) >= '0' && c <= '9') res = (res << 3) + (res << 1) + (c - 48); return bo ? ~res + 1 : res;}int main() { int i, j; n0 = read(); m0 = read(); p0 = read(); for (i = 0; i < p0; i++) cnt[i] = m0 / p0; for (i = 1; i <= m0 % p0; i++) cnt[i]++; P = cyx(p0, p0); P.v[1][1] = cnt[0]; for (i = 2; i <= p0; i++) P.v[1][i] = cnt[p0 - i + 1]; for (i = 2; i <= p0; i++) { for (j = 2; j <= p0; j++) P.v[i][j] = P.v[i - 1][j - 1]; P.v[i][1] = P.v[i - 1][p0]; } memset(prime, true, sizeof(prime)); prime[0] = prime[1] = 0; for (i = 2; i <= m0; i++) { if (!prime[i]) continue; if (i * i > m0) break; for (j = i * i; j <= m0; j += i) prime[j] = 0; } for (i = 1; i <= m0; i++) if (!prime[i]) cnt0[i % p0]++; Q = cyx(p0, p0); Q.v[1][1] = cnt0[0]; for (i = 2; i <= p0; i++) Q.v[1][i] = cnt0[p0 - i + 1]; for (i = 2; i <= p0; i++) { for (j = 2; j <= p0; j++) Q.v[i][j] = Q.v[i - 1][j - 1]; Q.v[i][1] = Q.v[i - 1][p0]; } for (i = 1; i <= p0; i++) for (j = 1; j <= p0; j++) P.v[i][j] %= CYX, Q.v[i][j] %= CYX; V = cyx(p0, 1); W = cyx(p0, 1); for (i = 1; i <= p0; i++) V.v[i][1] = cnt[i - 1] % CYX; for (i = 1; i <= p0; i++) W.v[i][1] = cnt0[i - 1] % CYX; P = (P ^ n0 - 1) * V; Q = (Q ^ n0 - 1) * W; printf("%d\n", (P.v[1][1] - Q.v[1][1] + CYX) % CYX); return 0;}
阅读全文
0 0
- [BZOJ4818][SDOI2017]序列计数(DP+容斥原理+矩乘)
- [BZOJ4818][Sdoi2017][容斥原理][矩阵优化DP]序列计数
- BZOJ4818 [Sdoi2017]序列计数
- BZOJ4818: [Sdoi2017]序列计数
- bzoj4818 [Sdoi2017]序列计数
- 【bzoj4818】[Sdoi2017]序列计数
- bzoj4818 [Sdoi2017]序列计数(矩阵)
- 【动态规划20】bzoj4818[sdoi2017]序列计数(dp+矩阵快速幂)
- BZOJ4818:序列计数(倍增+dp)
- LOj #2002. 「SDOI2017」序列计数 (容斥+dp+矩阵快速幂)
- bzoj 4818 [Sdoi2017]序列计数(简单容斥+快速幂加速dp)
- bzoj4818【SDOI2017】序列计数 矩阵快速幂+动态规划
- bzoj 4818 [Sdoi2017]序列计数 矩阵乘法优化dp+容斥
- bzoj 4818: [Sdoi2017]序列计数(DP+矩阵快速幂)
- [DP 倍增] BZOJ 4818 [Sdoi2017]序列计数
- 4818: [Sdoi2017]序列计数
- 【SDOI2017】序列计数
- 【BZOJ1042】[HAOI2008]硬币购物【计数DP】【容斥原理】
- Test 8 for NOIP- Result for Day2
- 函数可重入性(Reentrancy)
- 哇!这就是Makefile?
- CCF 201703-4 地铁修建(最小生成树 + 并查集)
- Linux帮助命令
- [BZOJ4818][SDOI2017]序列计数(DP+容斥原理+矩乘)
- sum HDU
- bzoj2333 [SCOI2011]棘手的操作
- a链接点击之后出现阴影
- laravel mvc组件创建
- python new方法
- c语言位运算有什么作用
- 已上线三个小程序,需要小程序开发的联系
- 百度第三代Spider是什么?