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 }
类似题目 https://ac.nowcoder.com/acm/contest/11746/B //K
实际也是要求子数组中的 %K==0 刚好利用前缀和的特性来做减法, 取模后 如果modk==0的话 相减一定为0

浙公网安备 33010602011771号