D.Multiple of 2019
Question
给一个字符串S,求有多少个子串在十进制下为2019的倍数。
Solution
前置知识:
若
若
则
这道题再增加难度就是任意模数
了二不一定是
,上面证明了任意模数P非10的因子的情况下。
下面讲如何处理
为
的因子情况下
从
到
遍历若一个数个位为
的因子,则前面的数肯定是
的倍数,所以前面的数被
取余一定为
。
对应的ABC158E
将题意转化为对2019求余为0的子串有多少个。求一个后缀模数数组,后缀数组取模后的数为
,后缀数组取模后为
的个数为
。
这里可以转化为加法,加上之前已有的
之后再更新
,注意初始化
。
Code ABC164D
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 2019;
const ll maxn = 1e6 + 5;
const int N = 2e5 + 5;
char s[N];
int a[N],suf[N],n,M[2020];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>s+1;
int n=strlen(s+1);
int cnt=0;int base=1;
M[0]++;
for(int i=n;i>=1;i--){
a[i]=s[i]-'0';
suf[i]=(suf[i+1]+a[i]*base)%mod;
cnt+=M[suf[i]];
M[suf[i]]++;
base=base*10%mod;
}
cout<<cnt<<'\n';
return 0;
}
Code2 ABC158E
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll maxn = 1e6 + 5;
const int N = 2e5 + 5;
char s[N];
int suf[N],cnt[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n,p;cin>>n>>p>>s+1;
int base=1;
ll ans=0;
if(10%p==0){
for(int i=1;i<=n;i++){
if((s[i]-'0')%p==0) ans+=i;
}
}else{
cnt[0]++;
for(int i=n;i>=1;i--){
int j=s[i]-'0';
suf[i]=(suf[i+1]+j*base)%p;
ans+=cnt[suf[i]];
cnt[suf[i]]++;
base=base*10%p;
}
}
cout<<ans<<'\n';
return 0;
}