【无码专区2】序列划分(数学)

有std,但是没有自我实现,所以是无码专区

description

完全由数字组成的字符串 sss,划分成若干段,每一段看成一个十进制的数(允许前导零)求有多少种划分方法使得相邻两个数至少一个是 DDD 的倍数。对 109+710^9+7109+7 取模。

数据:5×105,1065\times 10^5,10^65×105,106 级别。

我的想法

针对 30%30\%30% 的数据:n≤1000n\le 1000n1000n=∣s∣n=|s|n=s】。

dpi,0/1:dp_{i,0/1}:dpi,0/1: 划分在 iii 处,枚举上一个划分点 jjj,判断 (j,i](j,i](j,i] 是否是 DDD 的倍数 的方案数。

然后直接转移,就是 O(n2)O(n^2)O(n2) 的。

solution

对于另 20%:(D,10)=120\%:(D,10)=120%:(D,10)=1 就是提示正解的部分分。

Si=(∑si⋅10n−i)%DS_i=(\sum_{s_i}·10^{n-i})\%DSi=(si10ni)%D,即以 iii 开始的后缀对应的十进制数(在取模 DDD 的意义下)

判定条件: s[i,j]s[i,j]s[i,j] 组成的数能被 DDD 整除,当且仅当 Si=Sj+1S_{i}=S_{j+1}Si=Sj+1

dpi,0/1:dp_{i,0/1}:dpi,0/1: 从前往后划分到 iii ,当前段能否被 DDD 整除的方案数。

如果能被 DDD 整除,那么必须从 Sj=Si+1,1≤j<iS_j=S_{i+1},1\le j<iSj=Si+1,1j<i 转移过来,否则从不被整除的 SjS_jSj 转移过来。

用一个桶数组 cnti:Sj=icnt_i:S_j=icnti:Sj=idpjdp_jdpj 的和。

i.e.iii 转移被整除的信息的时候,相当于去找 cntSicnt_{S_i}cntSi 这个桶,dpi→cntSidp_i\rightarrow cnt_{S_i}dpicntSi

以上是 (D,10)=1(D,10)=1(D,10)=1,当 (D,10)≠1(D,10)\neq 1(D,10)=1 时,上述的判定条件就不完全对了。

改写 D=D1⋅D2D=D_1·D_2D=D1D2,其中 (D1,10)=1,D2=2a5b(D_1,10)=1,D_2=2^a5^b(D1,10)=1,D2=2a5b

改写 Si:S_i:Si:iii 开始到结尾形成的十进制数对 D1D_1D1 取模的结果。

改写判定条件:s[i,j]s[i,j]s[i,j] 组成的数能被 DDD 整除,当且仅当 Si=Sj+1∧D2∣s[i,j]S_i=S_{j+1}\wedge D_2\Big |s[i,j]Si=Sj+1D2s[i,j]

在十进制下 s[i,j]s[i,j]s[i,j] 要能被 2,52,52,5 的幂次整除,只需要看后面的若干位即可。

这里 D≤106≈220≈59D\le 10^6\approx 2^{20}\approx 5^9D10622059,所以最多看后面的 202020 位。

具体而言

  • 首先判断 s[i−19,i]s[i-19,i]s[i19,i] 组成的数是否 DDD 的倍数。
    • 是,再从桶里面找 cntSi+1→dpicnt_{S_{i+1}}\rightarrow dp_icntSi+1dpi
  • 暴力处理 s[j,i],i−19≤j≤i−1s[j,i],i-19\le j\le i-1s[j,i],i19ji1 判断是否是 DDD 的倍数,再 →dpi\rightarrow dp_idpi
  • 对于 j=i−19j=i-19j=i19iii 中间已经包含有 202020 位了【i−(i−19)+1=20i-(i-19)+1=20i(i19)+1=20】,所以 Sj→cntS_j\rightarrow cntSjcnt,可以入桶了。

参考code

#include <bits/stdc++.h>using namespace std;template <typename T>
T power(T a, long long b) {T r = 1;while (b) {if (b & 1) {r *= a;}a *= a;b >>= 1;}return r;
}template <typename T>
T inverse(T a, T m) {a %= m;if (a < 0) {a += m;}T b = m, u = 0, v = 1;while (a) {T t = b / a;b -= a * t;swap(a, b);u -= v * t;swap(u, v);}if (u < 0) {u += m;}return u;
}template <int _P>
struct modnum {static constexpr int P = _P;private:int v;public:modnum() : v(0) {}modnum(long long _v) {v = _v % P;if (v < 0) {v += P;}}explicit operator int() const {return v;}bool operator==(const modnum &o) const {return v == o.v;}bool operator!=(const modnum &o) const {return v != o.v;}modnum inverse() const {return modnum(::inverse(v, P));}modnum operator-() const {return modnum(v ? P - v : 0);}modnum operator+() const {return *this;}modnum &operator++() {v++;if (v == P) {v = 0;}return *this;}modnum &operator--() {if (v == 0) {v = P;}v--;return *this;}modnum operator++(int) {modnum r = *this;++*this;return r;}modnum operator--(int) {modnum r = *this;--*this;return r;}modnum &operator+=(const modnum &o) {v += o.v;if (v >= P) {v -= P;}return *this;}modnum operator+(const modnum &o) const {return modnum(*this) += o;}modnum &operator-=(const modnum &o) {v -= o.v;if (v < 0) {v += P;}return *this;}modnum operator-(const modnum &o) const {return modnum(*this) -= o;}modnum &operator*=(const modnum &o) {v = (int) ((long long) v * o.v % P);return *this;}modnum operator*(const modnum &o) const {return modnum(*this) *= o;}modnum &operator/=(const modnum &o) {return *this *= o.inverse();}modnum operator/(const modnum &o) const {return modnum(*this) /= o;}
};template <int _P>
ostream &operator<<(ostream &out, const modnum<_P> &n) {return out << int(n);
}template <int _P>
istream &operator>>(istream &in, modnum<_P> &n) {long long _v;in >> _v;n = modnum<_P>(_v);return in;
}using num = modnum<1000000007>;int main() {freopen("division.in", "r", stdin);freopen("division.out", "w", stdout);ios::sync_with_stdio(false);cin.tie(0);string s;int d;cin >> s >> d;int e = 1;while (d % 2 == 0) {d /= 2;e *= 2;}while (d % 5 == 0) {d /= 5;e *= 5;}int n = s.size();vector<int> a(n + 1);for (int i = 0; i < n; ++i) {a[i + 1] = (a[i] * 10 + (s[i] - '0')) % (d * e);}int inv10 = d == 1 ? 0 : inverse(10, d);vector<int> pw(n + 1);pw[0] = 1;for (int i = 0; i < n; ++i) {pw[i + 1] = (long long) pw[i] * inv10 % d;}vector<int> base(20);base[0] = 1;for (int i = 0; i + 1 < 20; ++i) {base[i + 1] = base[i] * 10 % (d * e);}vector<num> foo(n + 1), bar(n + 1);vector<num> offset_foo(d), offset_bar(d);bar[0] = 1;num pref = 0;for (int i = 0; i <= n; ++i) {foo[i] += pref;if (a[i] % e == 0) {foo[i] += offset_foo[(long long) a[i] * pw[i] % d];bar[i] += offset_bar[(long long) a[i] * pw[i] % d];}pref += bar[i];offset_foo[(long long) a[i] * pw[i] % d] -= bar[i];offset_bar[(long long) a[i] * pw[i] % d] += foo[i] + bar[i];for (int j = i + 1; j <= n && j < i + 20; ++j) {if ((a[j] - (long long) a[i] * base[j - i]) % (d * e) == 0) {foo[j] -= bar[i];bar[j] += foo[i] + bar[i];}if (a[j] % e == 0 && (long long) a[i] * pw[i] % d == (long long) a[j] * pw[j] % d) {foo[j] += bar[i];bar[j] -= foo[i] + bar[i];}}}cout << foo[n] + bar[n] << "\n";
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316890.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rinne Loves Edges

Rinne Loves Edges 题意&#xff1a; 有n给点&#xff0c;m个边&#xff0c;每个边有边权&#xff0c;给你一个点S&#xff0c;问最少花多少代价&#xff0c;可以让叶子节点无法与S点连通 题解&#xff1a; dp[u]:表示u到叶子节点的最短费用的和 dp[u]min(dp[v],w); 代码&…

.NET Core 中的 Generic Host快速使用指南

本文以自己在工作中学习和使用.net core generic-host 作一个总结。前言在创建的ASPNETCORE项目中&#xff0c;我们可以在Main()中看见&#xff0c;我们通过IWebHostBuild创建了一个IWebHost&#xff0c;而微软提供了WebHost.CreateDefaultBuilder(args)来帮助我们更轻松得创建…

CF1580B Mathematics Curriculum(笛卡尔树、树形dp)

解析 比较巧妙的一道题。 难点在于对题意的转化。 关键性质&#xff1a;符合要求的点等价于与笛卡尔树上深度为 mmm 的点。 原因也较为显然&#xff0c;考虑一个特定的点 xxx&#xff0c;当枚举全局最大值时&#xff0c;其会对 xxx 产生贡献&#xff0c;且最大值另一侧就和 xx…

CF1368G Shifting Dominoes(扫描线求矩阵的并集)

CF1368G Shifting Dominoesproblemsolutioncodeproblem 题目链接 solution 求的是最后棋盘本质不同的个数&#xff0c;而本质不同等价于两个空格位置不同。 如果想要移动一个多米诺骨牌&#xff0c;要求长边上下方有空位。 移动可以看成空位的移动。 所以我们考虑把一个 …

吉吉王国(二分+树形dp)

吉吉王国 题意&#xff1a; n个点&#xff0c;m个边&#xff0c;有边权&#xff0c;现在要求叶子节点无法与1号点连通&#xff0c;要求切断的总长度不能超过m&#xff0c;且切断的最长的长度尽可能断 题解&#xff1a; 题意的前半部分可以确定是树形dp&#xff0c;后半部分…

P3239 [HNOI2015]亚瑟王(期望)

解析 显然可以利用期望的线性性对每张牌单独计算贡献。 现在的关键就是如何求出每张牌被使用的概率。 考虑第 iii 张牌&#xff0c;如果它的前面 [1,i−1][1,i-1][1,i−1] 中有 jjj 张牌被使用&#xff0c;那么它被使用的概率就是 1−(1−pi)r−j1-(1-p_i)^{r-j}1−(1−pi​)…

微软一顿操作猛如虎,PowerShell 排名直线上升

近日&#xff0c;TIOBE 发布了 2019 年 3 月编程语言排行榜&#xff0c;PowerShell 首次进入到了榜单的 Top 50 中&#xff0c;排在第 45 位。PowerShell 是运行在 Windows 操作系统上实现对系统以及应用程序进行管理自动化的命令行脚本环境。&#xff08;PowerShell 排在了 TI…

CF1237F Balanced Domino Placements(dp+组合计数)

CF1237F Balanced Domino Placementsproblemsolutioncodeproblem 题目链接 solution 骨牌横着放会占用一行两列&#xff0c;骨牌竖着放会占用两行一列。 问题可以抽象为&#xff1a;每次可以选择连续的两行放 AAA&#xff0c;或选一行放 BBB&#xff1b;每次可以选一列放 B…

AcWing 201. 可见的点

AcWing 201. 可见的点 题意&#xff1a; 题解&#xff1a; 我们先说结论:坐标(i,j)&#xff0c;如果i和j互质&#xff0c;说明该坐标为可见 为什么&#xff1f; 我们想想什么样的坐标可见&#xff0c;什么样的会被挡住。光线是一个直线&#xff0c;在同一个直线上的点会被第一…

模板:LGV引理(线性代数)

所谓LGV引理&#xff0c;就是解决LGV问题的引理。 &#xff08;逃&#xff09; 前言 上联&#xff1a;古有学完SAM学PAM&#xff1b; 下联&#xff1a;今有学完Polya学LGV&#xff1b; 横批&#xff1a;小清新。 常被用于有向图不交路径计数问题。&#xff08;废话&#xff…

ocelot 自定义认证和授权

Intro最近又重新启动了网关项目&#xff0c;服务越来越多&#xff0c;每个服务都有一个地址&#xff0c;这无论是对于前端还是后端开发调试都是比较麻烦的&#xff0c;前端需要定义很多 baseUrl&#xff0c;而后端需要没有代码调试的时候需要对每个服务的地址都收藏着或者记在哪…

CF765F Souvenirs(势能线段树)

CF765F Souvenirsproblemsolutioncodeproblem 题目链接 solution 这个势能线段树简直是太巧妙了&#xff01;&#xff01;&#xff01;( ఠൠఠ )&#xff89; 将询问按右端点升序离线下来。 对于每一个右端点 rrr&#xff0c;维护 ansimin⁡{∣ai−aj∣,j∈[i,r]}ans_i\m…

P4849 寻找宝藏(模板:四维偏序)

stable_sort 保平安。 解析 dp方程显而易见&#xff0c;关键就是如何进行这个四维偏序的转移。 考虑三维偏序&#xff08;比如拦截导弹&#xff09;我们是如何做的&#xff1f; 先按照第一维排序&#xff0c;然后分治解决前一半&#xff0c;接下来把前一半的第一维看成0&…

AcWing 220. 最大公约数

AcWing 220. 最大公约数 题意&#xff1a; 题解&#xff1a; 题目就变成了AcWing 201. 可见的点 当然有微调&#xff0c;因为可见的点里面是从0开始&#xff0c;本题从1开始&#xff0c;所以本题中phi[1]认为是0 AcWing 201. 可见的点的题解 代码&#xff1a; #include<b…

2021 CSP-S 游记

2021CSP-S游记 从国庆过后就开始停课&#xff0c;确实面对的压力和挑战很大。 这段时间真的就是完全没有去想文化课那边的事。 越接近考试时间&#xff0c;模拟赛就越密集&#xff0c;最近大家都在互测。 蛮清楚自己的水平的&#xff0c;而且偶尔还是能考得不错&#xff0c…

欧拉函数(简单介绍+例题)

Acwing视频讲解 欧拉函数&#xff1a;正整数n&#xff0c;欧拉函数是小于n的正整数中与n互质的数的数目 Np1a1 * p1a2 * p1a3 * …* p1ak 如果pj是i的最小质因子 红色区域一样 经推导得&#xff1a;phi[i * pj] phi[i] * pj 如果pj不是i的最小质因子 经推导&#xff1a;phi[…

P5303 [GXOI/GZOI2019]逼死强迫症(斐波拉契、矩阵乘法)

解析 非常妙的一个题&#xff0c;感受到了斐波拉契优美的归纳性质。 首先&#xff0c;不难发现只要两个1*1的位置固定&#xff0c;中间的摆法就固定了&#xff0c;而两边的方案都是经典的斐波拉契数列&#xff08;设为 fif_ifi​&#xff09;。 那么枚举中间的间隔再枚举左边…

程序员过关斩将--你的面向接口编程一定对吗?

菜菜哥&#xff0c;出大事啦怎么了&#xff0c;你和男票分手了&#xff1f;很正常&#xff0c;谁让你男票是产经经理呢不是啦&#xff0c;是我做的一个小游戏&#xff0c;需求又变了&#xff0c;程序我快改不动了说来让我欢乐一下&#xff1f;菜菜哥&#xff0c;咱两还能不能好…

[2021 CSP-S提高组] 题解(廊桥分配+括号序列+回文+交通规划)

2021 CSP-S 题解廊桥分配括号序列回文交通规划配合&#x1f449;CSP-S游记 食用更佳哦~ 【雷】&#xff1a;只是在民间数据过了&#xff0c;不保证一定正确。仅供参考&#xff01;&#xff01;&#xff01; 【雷】&#xff1a;只是在民间数据过了&#xff0c;不保证一定正确。…

P1247 取火柴游戏

P1247 取火柴游戏 题意&#xff1a; 有n堆火柴&#xff0c;两个人轮流操作&#xff0c;每次只能在从一堆中取若干火柴&#xff0c;拿走最后一根火柴的为胜者&#xff0c;给你一个状态&#xff0c;问先手是赢是输 题解&#xff1a; 很经典的nim博弈&#xff0c;结论大家应该…