(f(l,r,k)=)区间[(l),(r)]的第k大。
(sum_{l=1}^{n}{sum_{r=l}^{n}{f(l,r,k)}})
参考题解,claris大佬题解。赛后AC。。。
题目链接
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <string>
using namespace std;
typedef long long int LL;
const int MOD = 1e9 + 7;
const int INF = 2e9 + 1e8;
const int maxn = 1e6 + 100;
struct dsajkbdsuhvjgfdwsaghvfewdsjhfcvdsghvfdsjhfbcgvdsgh
{
int pre,next,val;
}lst[maxn];
int pos[maxn],n,k;;
int temp[maxn];
void del(int x)
{
int pre=lst[x].pre,nxt=lst[x].next;
lst[pre].next=nxt;
lst[nxt].pre=pre;
}
LL calc(int x)
{
int lft[100],rit[100];
int il=0,ir=0;
for(int i=x;i>0;i=lst[i].pre)
{
lft[++il]=i-lst[i].pre;
if(il==k) break;
}
for(int i=x;i<=n;i=lst[i].next)
{
rit[++ir]=lst[i].next-i;
if(ir==k) break;
}
LL res=0;
for(int i=1;i<=il;i++)
{
if(k-i+1<=ir) res+=1ll*lft[i]*rit[k-i+1];
}
return res;
}
int main()
{
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
lst[i].pre=i-1,lst[i].next=i+1;
scanf("%d",&lst[i].val);
pos[lst[i].val]=i;
}
lst[0].next=1,lst[n+1].pre=n;
LL sum=0;
for(int i=1;i<=n-k+1;i++)
{
sum+=i*calc(pos[i]);
del(pos[i]);
}
cout<<sum<<endl;
}
return 0;
}