找所有区间的k大数。
模拟一下。这个代码算是险过吧,测试时间1700~1900.
AC代码:
#include <iostream>
#include <stdio.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 5*1e5+10;
int a[maxn]; ///存放数
int index[maxn];
int main()
{
int t,n,k,i,j;
LL ans;
scanf("%d",&t);
while(t--)
{
ans = 0;
scanf("%d%d",&n,&k);
for(i = 1; i <= n; i++)
scanf("%d",&a[i]);
a[0] = inf;
a[n+1] = inf;
for(i = 1; i <= n; i++)
{
int left = 0;
int right = 0;
index[k] = i; ///index数组存下标
for(j = i+1; j <= n+1; j++) ///往右边扫,找k个比a[i]大的数
{
if(a[j]>a[i])
{
right++;
index[k+right] = j;
}
if(right == k) break;
}
for(j = i-1; j >= 0; j--) ///往左边扫,找k个比a[i]大的数
{
if(a[j]>a[i])
{
left++;
index[k-left] = j;
}
if(left == k) break;
}
for(j = k+right-1; j >= k; j--)
{
if(j-k+1 < k-left+1) break;
int lnum,rnum;
lnum = index[j-k+1]-index[j-k]; ///新的序列,右边连续小于a[i]的个数
rnum = index[j+1]-index[j]; ///新的序列,左边连续小于a[i]的个数
ans += (LL)(lnum*rnum)*a[i];
}
}
printf("%lld\n",ans);
}
return 0;
}