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
Source
2020 Multi-University Training Contest 3
题意:
一个序列,可以合并相邻两个数。求最多可以得到多少个为p倍数的数
思路:
要是中间一段可以合并成p的倍数,那合并完以后肯定不用再管了。
所以可以直接从左到右维护前缀和%p的值,用map存下来,一旦前面出现过和当前前缀值相同的情况,则可以合并成一个p的倍数,就清空map。
dp思路的话, d p [ i ] = m a x ( d p [ i − 1 ] , d p [ l a s t [ n o w ] ] + 1 ) dp[i]=max(dp[i-1],dp[last[now]]+1) dp[i]=max(dp[i−1],dp[last[now]]+1)
last[now]代表当前前缀和上次出现的位置。
DP写法
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
int dp[maxn],last[maxn];
int main() {
int T;scanf("%d",&T);
while(T--) {
int n,p;scanf("%d%d",&n,&p);
memset(last,-1,sizeof(last));
int now = 0;
dp[0] = last[0] = 0;
for(int i = 1;i <= n;i++) {
int x;scanf("%d",&x);
now = (now + x) % p;
dp[i] = dp[i - 1];
if(last[now] != -1) {
dp[i] = max(dp[i],dp[last[now]] + 1);
}
last[now] = i;
}
printf("%d\n",dp[n]);
}
return 0;
}
map写法
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 2e7 + 7;
const int mod = 1e9 + 7;
unordered_map<int,int>mp;
int main() {
int T;scanf("%d",&T);
while(T--) {
int now = 0;
int n,p;scanf("%d%d",&n,&p);
int ans = 0;
for(int i = 1;i <= n;i++) {
int x;scanf("%d",&x);
now = (now + x) % p;
if(mp[now] || now == 0) {
ans++;
now = 0;
mp.clear();
} else {
mp[now] = 1;
}
}
printf("%d\n",ans);
}
return 0;
}