AtCoder Beginner Contest 164 D - Multiple of 2019 ###K ###K ###K ###K //K

题目链接:https://atcoder.jp/contests/abc164/tasks/abc164_d
题意:给定一个字符串,问其中又多少连续子序列的十进制数是2019的倍数

思路:因为10的幂次方肯定不是2019的倍数 也就是 10^k%2019!=0 那么位置的关系就不会影响只需要考虑具体的数字即可

也就是说 20190000 和2019 其实是一样的, 因为多乘的10倍并不会导致%2019==0

 

把字符串翻转一下,从头考虑   问题就转换成了区间内有多少个子区间的前缀和是相等的了  当然0的初始化为1

因为 x=a*2019+b y=c*2019+b  那么x-y 必然也是2019的倍数 并且这样维护出来值只是比 子区间的数值大了10^k  而且10和2019互质没有影响

不能够 sum+=x sum*=10 这样 因为这样 放的数 是错的  如 123 第一次放的是1  第二次放12 第三次123  实际应该放3 23 123

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pb push_back
 5 const int maxn =2e5+10;
 6 const int mod=1e9+7;
 7  
 8 int mp[3005];
 9  
10  
11  
12 int main()
13 {
14     ios::sync_with_stdio(false);
15     cin.tie(0);
16     string s;
17     cin>>s;
18     reverse(s.begin(),s.end());
19     int n=s.size();
20     ll ans=0;
21     ll now=0;
22     mp[0]=1;
23     ll c=1;
24     for(int i=0;i<n;i++)
25     {
26         int x=s[i]-'0';
27         if(i!=0)
28             c*=10;
29         c%=2019;
30         x*=c;
31         x%=mod;
32         now+=x;
33         now%=2019;
34         ans+=mp[now];
35         mp[now]++;
36  
37     }
38     cout<<ans<<'\n';
39  
40  
41  
42  
43  
44 }
View Code

 

类似题目  https://ac.nowcoder.com/acm/contest/11746/B   //K

实际也是要求子数组中的 %K==0  刚好利用前缀和的特性来做减法, 取模后 如果modk==0的话 相减一定为0 

posted @ 2020-08-20 21:45  canwinfor  阅读(171)  评论(0)    收藏  举报