AtCoder ABC 158E Divisible Substring
题目链接:https://atcoder.jp/contests/abc158/tasks/abc158_e
题目大意
给定一个长度为$N$的数字字符串,问有多少个子串模$P$等于零(子串可以有前导零)。
分析
以一个7位数abcdefg为例。
如果已知$efg~\%~P~==~r$和$bcdefg~\%~P~==~r$,是否可以得出$bcd~\%~P~==~0$呢?
答案是不能的,因为假设的两个条件只能得出$1000~*~bcd~\%~P~==~0$,也就是说,因为要多乘1000得关系,无法使之与$bcd~\%~P~==~0$等价。
但如果$P$不为$2$或$5$,1000就不会产生影响,也就可以和$bcd~\%~P~==~0$等价。
而对于$P$为$2$或$5$的情况,可以直接根据末尾数字的值来判断能不能被整除。
代码如下
1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 /*-------------------Define Start-------------------*/ 6 typedef bool BL; // 布尔类型 7 typedef char SB; // 有符号1字节,8位 8 typedef unsigned char UB; // 无符号1字节,8位 9 typedef short SW; // 有符号短整型,16位 10 typedef unsigned short UW; // 无符号短整型,16位 11 typedef long SDW; // 有符号整型,32位 12 typedef unsigned long UDW; // 无符号整型,32位 13 typedef long long SLL; // 有符号长整型,64位 14 typedef unsigned long long ULL; // 无符号长整型,64位 15 typedef char CH; // 单个字符 16 typedef float R32; // 单精度浮点数 17 typedef double R64; // 双精度浮点数 18 19 #define Rep(i, n) for (register SDW i = 0; i < (n); ++i) 20 #define For(i, s, t) for (register SDW i = (s); i <= (t); ++i) 21 #define rFor(i, t, s) for (register SDW i = (t); i >= (s); --i) 22 #define foreach(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i) 23 #define ms0(a) memset(a,0,sizeof(a)) 24 #define msI(a) memset(a,0x7f,sizeof(a)) 25 #define LOWBIT(x) ((x)&(-x)) 26 27 #define MP make_pair 28 #define PB push_back 29 #define ft first 30 #define sd second 31 #define ALL(x) x.begin(),x.end() 32 33 #define pr(x) cout << #x << " = " << x << " " 34 #define prln(x) cout << #x << " = " << x << endl 35 36 #define lson l , mid , rt << 1 37 #define rson mid + 1 , r , rt << 1 | 1 38 39 const ULL mod = 1e9 + 7; //常用模数(可根据题目需要修改) 40 const ULL inf = 0x7fffffff; //用来表示无限大 41 const ULL infLL = 0x7fffffffffffffffLL; //用来表示无限大 42 /*-------------------Define End-------------------*/ 43 44 const UDW maxN = 1e4 + 7; 45 SDW N, P; 46 string S; 47 SLL r[maxN]; // 存余数个数 48 SLL ans; 49 50 51 void input(){ 52 cin >> N >> P >> S; 53 } 54 55 void solve(){ 56 if(P == 2 || P == 5) { 57 rFor(i, N - 1, 0) { 58 if((S[i] - '0') % P == 0) { 59 ans += i + 1; 60 } 61 } 62 } 63 else{ 64 SLL base = 1; 65 SLL x = 0; 66 r[0] = 1; 67 68 rFor(i, N - 1, 0) { 69 x = (x + (S[i] - '0') * base) % P; 70 ans += r[x]; 71 ++r[x]; 72 base = (base * 10) % P; 73 } 74 } 75 } 76 77 void output(){ 78 cout << ans << endl; 79 } 80 81 int main() { 82 input(); 83 solve(); 84 output(); 85 return 0; 86 }