P4349 [CERC2015]Digit Division 思维题 数论

题意:

有一个\(N\)位的数字,将其分割,保证每个区间里的数字可以被\(M\)整除,输出方案数,答案对\(10^9+7\)取模

范围&性质:\(1\le N\le 3\times10^5,1\le M\le 10^6\)

分析:

第一眼\(O(n^2)\)DP,一看数据范围,放弃。思考怎么优化,我们发现对于DP来说,每一个点都是由之前能够断开的地方转移而来,那么影响答案的只有可划分的间隔,所以\(O(n)\)的扫一遍记录能够断开的区间个数,且两个断点之间的区间一定能被\(M\)整除,最后只需要判断一下最后一段区间能否被\(M\)整除,若可以,那么答案就是$ 2^{断点个数} $

代码:

#include<bits/stdc++.h>

using namespace std;

namespace zzc
{
	const int mod = 1e9+7;
	const int maxn = 3e5+5;
	char ch[maxn];
	int n,m,cnt=0,tmp=0;
	
	long long qpow(int x,int y)
	{
		long long res=1;
		while(y)
		{
			if(y&1) res=res*x%mod;
			x=(long long)x*x%mod;
			y>>=1;
		}
		return res;
	}
	
	void work()
	{
		scanf("%d%d",&n,&m);
		scanf("%s",ch+1);
		for(int i=1;i<n;i++)
		{
			tmp=(tmp*10+ch[i]-'0')%m;
			if(!tmp)
			{
				cnt++;
			}
		}
		tmp=(tmp*10+ch[n]-'0')%m;
		if(tmp)
		{
			printf("0\n");
			return ;
		}
		else printf("%lld",qpow(2,cnt));
	}
	
}

int main()
{
	zzc::work();
	return 0;
 } 
posted @ 2020-09-16 20:50  youth518  阅读(136)  评论(0编辑  收藏  举报