AtCoder Beginner Contest 158 E.Divisible Substring

題目鏈接
思路:
sis_i[i,n][i,n]構成的十進制數。
[l,r][l,r]構成的十進制數是p的倍數,則:
slsr+110nr=0  (mod  p)\frac{s_l-s_{r+1}}{10^{n-r}}=0~~(mod~~p)
如果gcd(10,p)=1gcd(10,p)=1的話,10x mod p10^{x}~mod~p是非零的,所以slsr+1=0, mod ps_l-s{r+1}=0,~mod~p,即sl=sr+1, mod ps_l=s_{r+1},~mod~p
那麼直接記錄一下後綴的十進制表示%p後的值出現次數就可以了。
gcd(10,p)!=1gcd(10,p)!=1即p=2或5的時候,直接跑個dp就好了。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
int n,p;
char a[N];
LL vis[N];
LL f[N][10];
int main() {
  ios::sync_with_stdio(false);
  cin>>n>>p>>a+1;
  if(p>=10){
    int pre=0;
    LL ans=0;vis[0]=1;
    LL c=1;
    for(int i=n;i>=1;i--,c=c*10%p){
      pre=(pre+(a[i]-'0')*c)%p;
      ans+=vis[pre];
      vis[pre]++;
    }
    cout<<ans<<'\n';
  }else{
    LL ans=0;
    for(int i=1;i<=n;i++){
      for(int j=0;j<p;j++){
        f[i][(j*10+a[i]-'0')%p]+=f[i-1][j];
      }
      f[i][(a[i]-'0')%p]++;
      ans+=f[i][0];
    }
    cout<<ans<<'\n';
  }

  return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章