hdu 6058

(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;
}

原文地址:https://www.cnblogs.com/coded-ream/p/7273167.html