Problem Description
Tokitsukaze has a sequence of length n, denoted by a.
Tokitsukaze can merge two consecutive elements of a as many times as she wants. After each operation, a new element that equals to the sum of the two old elements will replace them, and thus the length of a will be reduced by 1.
Tokitsukaze wants to know the maximum possible number of elements that are multiples of p she can get after doing some operations (or doing nothing) on the sequence a.
Input
There are several test cases.
The first line contains an integer T (1≤T≤20), denoting the number of test cases. Then follow all the test cases.
For each test case, the first line contains two integers n and p (1≤n,p≤105), denoting the length of the sequence and the special number, respectively.
The second line contains n integers, where the i-th integer ai (1≤ai≤105) is the i-th element of a.
It is guaranteed that the sum of n in all test cases is no larger than 106.
Output
For each test case, output in one line the maximum possible number of elements that are multiples of p after doing some operations.
Sample Input
2
5 3
2 1 3 2 1
3 1
123 456 789
Sample Output
3
3
题意:给你一个数字序列,问你最多能选出几个子段,使得每段和恰好是p的倍数。
思路:考虑前缀数组。从左至右判断,当有两个前缀和相等时,这段区间和就一定是 p 的倍数
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
int T;
int n, p;
ll sum[N];
int num[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
while (T--)
{
memset(num, -1, sizeof num);
cin >> n >> p;
for (int i = 1; i <= n; i++)
{
ll x;
cin >> x;
sum[i] = sum[i - 1] + x;
}
int ed = 0;
num[0] = 0;
int ans = 0;
for (int i = 1; i <= n; i++)
{
int temp = sum[i] % p;
if (num[temp] >= ed)
{
ans++;
ed = i;
}
num[temp] = i;
}
cout << ans << endl;
}
}