题目大意:给定一个数字串,要求分成三段
A,B,C
,满足
A,B,C
都不含前导零且
p|A,q|B,r|C
“不含前导零”这个条件只是在增加细节,我们无视他
首先枚举
A
和
然后倒着枚举
B和C
的分界线,对于每个位置,首先删除与
R
与
然后加上“不含前导零”这个条件就是多了一堆细节。。。慢慢讨论吧艹
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 1001001
using namespace std;
int n,p,q,r;
long long ans;
char s[M];
int a[M],L[M],R[M],cnt[100100];
int main()
{
int i,pow10_mod_q=1,pow10_mod_r=1;
cin>>n>>p>>q>>r;
scanf("%s",s+1);
for(i=1;i<=n;i++)
{
a[i]=s[i]-'0';
L[i]=(L[i-1]*10+a[i])%p;
}
for(i=n;i;i--,(pow10_mod_q*=10)%=q)
R[i]=(R[i+1]+a[i]*pow10_mod_q)%q;
for(i=1;i<n;i++)
{
if( a[1]==0 && i!=1 )
continue;
if( a[i+1]==0 )
continue;
if( L[i]==0 )
cnt[R[i+1]]++;
}
int C_mod_q=0,C_mod_r=0;
for(pow10_mod_q=1,i=n;i>=3;i--,(pow10_mod_q*=10)%=q,(pow10_mod_r*=10)%=r)
{
(C_mod_q+=a[i]*pow10_mod_q)%=q;
(C_mod_r+=a[i]*pow10_mod_r)%=r;
if( a[i]!=0 && L[i-1]==0 )
cnt[R[i]]--;
if( a[i]!=0 || i==n )
if(C_mod_r==0)
ans+=cnt[C_mod_q];
if( C_mod_r==0 && a[i-1]==0 && L[i-2]==0 && (a[1]!=0||i==2) && (a[i]!=0||i==n) )
++ans;
}
cout<<ans<<endl;
return 0;
}