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 }
View Code

 

posted @ 2020-03-15 18:02  梦樱羽  阅读(298)  评论(0编辑  收藏  举报
Live2D