Kanade's sum
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 494 Accepted Submission(s): 170
Problem Description
Give you an array
A[1..n]
of length
n
.
Let f(l,r,k) be the k-th largest element of A[l..r] .
Specially , f(l,r,k)=0 if r−l+1<k .
Give you k , you need to calculate ∑nl=1∑nr=lf(l,r,k)
There are T test cases.
1≤T≤10
k≤min(n,80)
A[1..n] is a permutation of [1..n]
∑n≤5∗105
Let f(l,r,k) be the k-th largest element of A[l..r] .
Specially , f(l,r,k)=0 if r−l+1<k .
Give you k , you need to calculate ∑nl=1∑nr=lf(l,r,k)
There are T test cases.
1≤T≤10
k≤min(n,80)
A[1..n] is a permutation of [1..n]
∑n≤5∗105
Input
There is only one integer T on first line.
For each test case,there are only two integers n , k on first line,and the second line consists of n integers which means the array A[1..n]
For each test case,there are only two integers n , k on first line,and the second line consists of n integers which means the array A[1..n]
Output
For each test case,output an integer, which means the answer.
Sample Input
1 5 2 1 2 3 4 5
Sample Output
30
解:找到一个点,先往右边找合法区间,再往左边找合法区间(当前值为第K大)
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+7;
typedef long long LL;
const LL mod = 1e9+7;
int a[N], b[N], pos[N];
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n, k;
scanf("%d %d", &n, &k);
for(int i=1;i<=n;i++) scanf("%d", &a[i]);
LL ans=0;
for(int i=1;i<=n;i++)
{
if(i==8)
{
int h1=0;
}
int x=a[i], cnt=0, j, sum=0;
b[++cnt]=i;
for(j=i+1;j<=n&&cnt<k;j++)
if(a[j]>x) b[++cnt]=j;
if(cnt==k)
{
int num=1;
for(;j<=n;j++)
{
if(a[j]<x) num++;
else break;
}
sum+=num;
for(j=i-1;j>=1&&cnt>=1;j--)
{
if(a[j]<x) sum+=num;
else
{
if(cnt==1) break;
num=b[cnt]-b[cnt-1];
cnt--;
sum+=num;
}
}
}
else
{
for(j=i-1;j>=1&&cnt<k;j--)if(a[j]>x) b[++cnt]=j;
if(cnt==k)
{
sort(b+1,b+cnt+1);
int num=n-b[cnt]+1;
sum+=num;
for(;j>=1&&b[cnt]>=i;j--)
{
if(a[j]<x) sum+=num;
else
{
if(b[cnt]==i) break;
num=abs(b[cnt]-b[cnt-1]);
cnt--;
sum+=num;
}
}
}
}
//printf("%d %d\n",i, sum);
ans+=(LL)x*sum;
}
printf("%lld\n",ans);
}
return 0;
}