Title Description
Given a length of n-$ $ $ A $ sequence and the constant $ k $, $ sequence numbered starting from $ 1.
Referred
$$ f (l, t) = \ sum \ limits_ {i = l} ^ ra_i- \ max \ limits_ {i = l} ^ r \ {a_i \} $$
positive integer legal requirements of $ (l, R & lt number) $ satisfy $ 1 \ leqslant l <r \ leqslant n $, and $ k | f (l, r ) $.
Input Format
The first line of two positive integers n-$ $ and $ k $.
The second line contains n-$ $ positive integer, the $ I $ positive integer $ a_i $.
Output Format
Line a positive integer representing the answer.
Sample
Sample input 1:
4 3
1 2 3 4
Sample output 1:
3
Sample input 2:
4 2
4 4 7 4
Sample Output 2:
6
Data range and tips
For $ 30 \% $ data, $ n \ leqslant 3,000 $;
for additional $ 20 \% $ data series $ A $ is randomly generated;
for $ 100 \% $ data, $ 1 \ leqslant n \ leqslant 3 \ times { 10} ^ 5,1 \ leqslant k \ leqslant {10} ^ 6,1 \ leqslant a_i \ leqslant {10} ^ 9 $.
answer
Consider divide and conquer, but I play with positive solutions are not the same.
$ Solve (l, r) on behalf of the endpoint are about $ $ [l, r] $ interval between legitimate number.
Clearly, we certainly can not turn enumerate each endpoint, so the time complexity is $ \ Theta (n ^ 2) $, so we consider optimization.
We can refer to enumerate one side, and then calculate the answer to this side when dealing with the other side.
Time complexity: $ \ Theta (n \ log n) $.
Desired points: $ 100 $ points.
The actual sub-: $ 100 $ points.
Code time
#include<bits/stdc++.h>
using namespace std;
int n,k;
int a[300001];
int s[300001];
int maxn[300001],pos[300001];
int t1[10000001],t2[10000001];
long long ans;
void wzc(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1;
int flag1=1,flag2=mid+1,mx=0;
s[0]=s[mid]=maxn[0]=0;
for(int i=mid+1;i<=r;i++)
{
if(a[i]>a[maxn[maxn[0]]])maxn[++maxn[0]]=i;
s[i]=(s[i-1]+a[i])%k;
t1[(s[i]-a[maxn[maxn[0]]]%k+k)%k]++;
pos[i]=maxn[maxn[0]];
}
maxn[maxn[0]+1]=r+1;
for(int i=mid;i>=l;i--)
{
s[0]=(s[0]+a[i])%k;
mx=max(mx,a[i]);
while(flag1<=maxn[0]&&a[maxn[flag1]]<=mx)flag1++;
while(flag2<maxn[flag1])
{
t1[(s[flag2]-a[pos[flag2]]%k+k)%k]--;
t2[s[flag2++]]++;
}
if(flag1<=maxn[0])ans+=t1[(k-s[0])%k];
ans+=t2[(mx%k-s[0]+k)%k];
}
for(int i=mid+1;i<flag2;i++)t2[s[i]]--;
for(int i=flag2;i<=r;i++)t1[(s[i]-a[pos[i]]%k+k)%k]--;
wzc(l,mid);
wzc(mid+1,r);
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
wzc(1,n);
printf("%lld",ans);
return 0;
}
rp ++