hdu 6058 Kanade's sum

来源:互联网 发布:java web基础知识书籍 编辑:程序博客网 时间:2024/06/14 03:45

题意:

找到 l (1~n ) r(l~n)的第k大的和。

思路:

当时想明白了。没写对。。看了下别人代码。。模拟链表。

先每次找到最小值,然后访问左侧和右侧,乘起来之后,更新左侧右侧指针。


#include <stdio.h>#include <algorithm>#include <cstring>using namespace std;const int maxn=500005;int nxt[maxn],pre[maxn];int id[maxn],pos[maxn];int l[maxn],r[maxn];int k,n;long long  solve(int x){    int left=0,right=0;    for(int i=x;i!=0&&left<=k;i=pre[i])    {        l[++left]=i-pre[i];    }    for(int i=x;i<=n&&right<=k;i=nxt[i])    {        r[++right]=nxt[i]-i;    }    long long  ans=0;    for(int i=1;i<=left ;i++)    {        if(k-i+1<=right&&k-i+1>=1)        ans+=(l[i]*r[k-i+1]);    }    return ans;}void del(int x){    pre[nxt[x]]=pre[x];    nxt[pre[x]]=nxt[x];}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&k);        int x;        for(int i=1;i<=n;i++)        {            scanf("%d",&x),id[x]=i;        }        pre[0]=0,nxt[n+1]=n+1;        nxt[0]=1,pre[n+1]=n;        for(int i=1;i<=n;i++)        {            pre[i]=i-1;            nxt[i]=i+1;        }        long long ans=0;        for(int i=1;i<=n;i++)        {            ans+=(long long )i*(solve(id[i]));            del(id[i]);        }        printf("%lld\n",ans);    }}


原创粉丝点击