UVALive 7327【模拟】

题意:

每次方案一个或多个子序列;

每个子序列要整除m

认为分割不同,子序列边界的不同就是不同;

1246有4个

1246

12 46

124 6

12 4 6

思路:

先从整体考虑,因为取膜适用于加法,所以一个数拆分成两个数%m==0就代表这个数%m一定=0;

再考虑把原串划分成两段,当且仅当某个前缀组成的数能被m整除时,原串才能被分成两段.

划成多段同理.

求出有多少地方能被切割,结果就是 2^(res-1). 就是相当于枚举每个位置切割or不切割结果.

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std; typedef long long LL;
const int N=3e5+10;
const LL mod=1e9+7;
char s[N]; LL cal(LL g,LL x)
{
LL ans=1;
while(g)
{
if(g%2) ans=(ans*x)%mod;
x=(x*x)%mod;
g>>=1;
}
return ans;
} int main()
{
LL n;
LL m;
while(~scanf("%lld%lld",&n,&m))
{
LL res=0;
LL temp=0;
scanf("%s",s);
for(LL i=0;i<n;i++)
{
temp=(temp*10LL+s[i]-'0')%m;
if(!temp)
res++;
}
if(temp)
{
puts("0");
continue;
}
printf("%lld\n",cal(res-1,2));
}
return 0;
}
上一篇:android开发类似coverflow效果的3d旋转


下一篇:UVALive - 7139(差分+模拟)