首页 > 其他分享 >[CERC2015] Digit Division 题解

[CERC2015] Digit Division 题解

时间:2024-09-27 12:13:37浏览次数:7  
标签:Division Digit 前缀 int 题解 sum 拆分 整除 数字

\(O(n^2)\) 做法

和大部分人最开始一样,我也想的是 DP。

设 \(dp_i\) 表示用前面 \(i\) 个字符拆分得到的答案。既然是统计方案数,我们肯定是根据前面的答案累加。考虑在 \([1,i-1]\) 中选择一个 \(j\),如果 \([j+1,i]\) 的字符组成的数字能够被 \(m\) 整除,那么 \(dp_i\) 就可以累加一个 \(dp_j\) 的值,因为如果当前区间满足条件,就相当于这里是一个可行的拆分,那么前面 \(j\) 个字符得到的答案很明显也都可以成为累加的一部分。

假设 \(flag_{j,i}\) 表示区间 \([j,i]\) 组成的数字是否可以被 \(m\) 整除,\(1\) 表示可以,\(0\) 表示不可以。则有转移方程:

\[dp_i= \sum _{j=1}^{i-1}dp_j \times flag_{j+1,i}\]

那么答案就是在 \(dp_{n}\) 这里了。

此做法时间复杂度为 \(O(n^2)\),而 \(n \leq 3\times 10^5\),并且无法进行优化,所以 DP 只能进行骗分。

\(O(n)\) 做法

考虑运用数学运算进行求解。

设想一下,假如字符串的前缀组成的数字 \(x\) 能够被 \(m\) 整除会怎么样?如果整个字符串组成的数字 \(sum\) 也能够被 \(m\) 整除,那么这个前缀以后的所有字符组成的数字也必定可以被 \(m\) 整除。即 \(m\mid sum-x\times 10^{num}\),其中 \(num\) 是非前缀的字符个数。这个是非常容易想到的一个式子。

那么这样的一个式子有什么用呢?既然前缀后面的数字可以被 \(m\) 整除,那么我们能否按照相同的思路,在这之中进行拆分?假设后面的数字为 \(sum\),在这个数字里面找一个前缀组成数字 \(x\),由上文第一步推断知道 \(m\mid sum\),如果此时 \(m\mid x\),那么这个前缀后面的数字也可以被 \(m\) 整除,这个思路和上文一模一样。

所以我们可以得出一个结论,如果整个字符串的某个前缀组成的数字能被 \(m\) 整除,且整个字符串组成的数字能够被 \(m\) 整除,那么此时这个前缀的最后一个字符的下标处就是一个可以进行拆分的地方。如果在这里进行拆分,那么前后的字符串也都会被 \(m\) 整除,因此这里一定会被某一个拆分方式进行拆分。

所以我们可以找到所有被 \(m\) 整除的前缀数字,记录下这样的前缀的个数 \(res\)。然后这个问题就转化成了对 \(res\) 个可以拆分的地方进行组合。因为这里面的前缀会包括整个字符串,所以中间选择的拆分的地方有 \(res-1\) 个。由于每个地方有选与不选的 \(2\) 种可能,因此计算的答案就是 \(2^{res-1}\) 次方。而求幂我们使用快速幂就可以了。

一定要注意,如果整个字符串组成的数字不能被 \(m\) 整除,那么答案一定是 \(0\),因为找不到任何一个拆分的地方,使得前后两个数字都能够被 \(m\) 整除。

代码如下:

#include<bits/stdc++.h>
#define int long long//方案取模题,日常开 long long 
using namespace std;
const int MAXN=3e5+5;
const int MOD=1e9+7;
int n,m;
char s[MAXN];
int quick_pow(int x)//2^x的快速幂 
{
	int ans=1,sum=2;
	while(x)
	{
		if(x&1)	ans=ans*sum%MOD;
		sum=sum*sum%MOD;
		x>>=1;
	}
	return ans;
}
signed main()
{
	cin>>n>>m>>(s+1);
	int res=0,x=0;
	for(int i=1;i<=n;i++)	x=(x<<1)+(x<<3)+(s[i]^48),x%=m,res+=(!x);//计算可拆分地方的个数 
	if(x)	puts("0");//特判 
	else	cout<<quick_pow(res-1);//组合 
	return 0;
}

标签:Division,Digit,前缀,int,题解,sum,拆分,整除,数字
From: https://www.cnblogs.com/SuporShoop/p/18435410

相关文章

  • [JLOI2015] 有意义的字符串 题解
    拿到题目,我们首先分析一下这个奇怪的式子:\[\lfloor(\frac{b+\sqrt{d}}{2})^n\rfloor~\text{mod}~p\]重点肯定是在里面的那个式子里面,最显眼的肯定也就是那个\(\sqrt{d}\),根据整体形式,我们可以联系一元二次方程的求根公式\(x=-\dfrac{-b\pm\sqrt{b^2-4ac}}{2a}\),这里也是一......
  • 「KDOI-06-S」消除序列 题解
    分享一个应该很少人想到的做法。首先贪心地想,第一种操作肯定最多选择一次。比如如果选择了下标\(i\)和\(j\)进行第一种操作,那么就等价于在\(\max\{i,j\}\)进行了一次操作。由于代价是非负数,则我们最多只用执行一次。当然也可以不使用这种操作。有了这个思路,我们先考虑不使......
  • 「TAOI-2」Ciallo~(∠・ω< )⌒★ 题解
    手玩了一个小时终于做出来了,这不得写一篇题解记录一下??下面设\(s\)的长度为\(n\),\(t\)的长度为\(m\)。考虑分类讨论:如果\(s\)中有一个子串\(s'\)与\(t\)完全相同(可以用哈希进行比较),设\(s'\)是\(s\)的第\(l\)到第\(r\)个字符组成的字符串,则我们可以删除\([1,......
  • 三星G8 OLED显示器S34BG850SC,使用DP线连接电脑,显示器黑屏问题解决。
    这个问题在网上好像很多人问,但是每个人的情况不同,总之我也是遇到了。事情大概:PC机显卡的DP口通过显示器自带的MiniDP线和显示器相连,这个没什么好说的了,原配只送MiniDP线,想必买这台显示器的人都是先用的这根线。然而我有一台NUC,通过雷电口也连接到了这台显示器。所以我这台G8是......
  • [TJOI2010] 天气预报 题解
    分析一下题目,大致意思就是给定一组常数\(a_i\),然后有一个递推式\(w_i=\sum_{j=1}^{n}w_{i-j}\timesa_{j}\),让你求出\(w_m\)对于\(4147\)取模的值。根据这个\(1\leqm\leq10^7\)的恐怖范围,姑且算到了\(O(m)\)的时间复杂度。但是观察一下这个递推式,发现\(O(m)\)跑......
  • ABC262G 题解
    LISwithStack观察到\(n\le50\),考虑区间dp。设\(dp(l,r,x,y)\)表示区间\([l,r]\)中选出的子序列的最小值\(\gex\),最大值\(\ley\)的方案数。根据栈的性质,设元素\(x\)入栈的时间为\(in_x\),出栈时间为\(out_x\),那么所有元素构成的区间\([in_x,out_x]\)两......
  • 2024-2025专题二题单 - 题解
    A-MoneyinHand(记忆化搜索)原题链接题解B-GoodGraph(并查集)原题链接题解C-IceSkating(dfs求连通块)原题链接题解D-TheLakes(dfs求连通块,连通块内累加,多组数据注意初始化)原题链接题解E-LearningLanguages(建图,dfs统计连通块个数,答案为个数-1)原题链接题......
  • 进击的奶牛题解
    题目描述FarmerJohn建造了一个有 N(2≤N≤105)个隔间的牛棚,这些隔间分布在一条直线上,坐标是 x1,x2,⋯ ,xN​(0≤xi≤109)。他的 C(2≤C≤N)头牛不满于隔间的位置分布,它们为牛棚里其他的牛的存在而愤怒。为了防止牛之间的互相打斗,FarmerJohn想把这些牛安置在指定的隔间,所......
  • 奶牛分厩题解
    题目描述农夫约翰有 N(1≤N≤5000)头奶牛,每头奶牛都有一个唯一的不同于其它奶牛的编号 s[i],所有的奶牛都睡在一个有 K 个厩的谷仓中,厩的编号为 00 到 K−1。每头奶牛都知道自己该睡在哪一个厩中,因为约翰教会了它们做除法,Si mod K的值就是第 i 头奶年所睡的厩的编......
  • 易优cms安全设置常见问题_Eyoucms安全设置问题解决方法
    易优EyouCMS的安全设置对于保护网站免受攻击非常重要。下面列出了一些关于易优CMS安全设置的常见问题及其解决方法:1.目录权限设置为了防止未经授权的访问,应该合理设置网站目录的权限。例如,上传目录通常需要写入权限,而其他目录则应限制权限以防止恶意文件上传或执行。解决方法......