Kanade's sum
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2296 Accepted Submission(s): 947
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
Source
Recommend
题意:给你n个数,这n个数是一种全排列,问你所有子区间的第k大的数之和。
题解:因为是全排列,从1到n枚举当前第k大的值即可,开两个数组,pre和nxt分别标记当前点往左右延伸的长度就是该点的贡献,之后求波和即可。。
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<math.h>
#include<time.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 2147483647
#define mod 1000000007
#define maxn 5000005
#define lowbit(x) (x&-x)
#define eps 1e-10
int pre[maxn],nxt[maxn],pos[maxn];
int main(void)
{
ll sum,ans;
int n,k,i,j,x,l,r,T;
scanf("%d",&T);
while(T--)
{
sum=0;
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++)
{
scanf("%d",&x);
pos[x]=i;pre[i]=i-1;nxt[i]=i+1;
}
pre[0]=0;nxt[n+1]=n+1;
for(j=1;j<=n;j++)
{
int rc[100];
r=l=0;x=pos[j];ans=0;
for(i=x;i<=n && r<k;i=nxt[i])
rc[++r]=nxt[i]-i;
for(i=x;i>0 && l<k;i=pre[i])
{
l++;
if(k-l+1>r)
continue;
ans+=(i-pre[i])*rc[k-l+1];
}
sum+=ans*j;
pre[nxt[x]]=pre[x];
nxt[pre[x]]=nxt[x];
}
printf("%lld\n",sum);
}
return 0;
}