题目链接:https://www.luogu.com.cn/problem/P8649
思路:
看到区间和,第一反应肯定是前缀和,我们求出前缀和后对前缀和数组每一个值模k,然后对一个数组的值查看前面有几个相同的,举个例子:
样例中前缀和数组a取模后为:1 1 0 0 1
下标依次为1 2 3 4 5
当题目所求子序列以a5结尾时,已知a5=1且a5前面与a5相同的值有2个,则以a5结尾可以获得2个满足题目要求的区间
如果以a3结尾则是一个,因为实际上有一个a0=0。
#include<bits/stdc++.h>using namespace std;using ll = long long;
const ll N = 3e5 + 5;
const ll mod = 1e9 + 7;
int gcd(int a, int b) {return b ? gcd(b, a % b) : a;
}void solve() {int n; cin >> n;ll k; cin >> k;vector<ll>a(n + 1);vector<ll>pre(n + 1);vector<ll>cnt(n + 1);for (int i = 1; i <= n; i++) {cin >> a[i];pre[i] = pre[i - 1] + a[i];}ll ans = 0;cnt[0] = 1;for (int i = 1; i <= n; i++) {ans += cnt[pre[i] % k];cnt[pre[i] % k]++;}cout << ans << '\n';
}signed main() {ios::sync_with_stdio(false);cin.tie(0);std::cout.tie(0);int t1 = 1;//cin >> t1;while (t1--)solve();return 0;
}