2017第三次多校联合hdu6058

来源:互联网 发布:中信淘宝信用卡权益 编辑:程序博客网 时间:2024/06/05 10:25

题目
题意:给你n,k和序列A,求nl=1nr=1f(l,r,k)

题解:便利数组元素,找每一个点ai左右各K个比它的大的数,记下与
ai的距离,然后组合一下看看有多少种可能能组成使ai成为第K大数,然后求和。
ps:这个方法是巧妙的暴力。如果运气不好会超时。。。

#include<bits/stdc++.h>using namespace std;const int maxn=5e5+5;int a[maxn],l[maxn],r[maxn];long long ans=0;int main(){    //freopen("data.in", "r", stdin);    int t;    scanf("%d",&t);    while(t--)    {        memset(a,0,sizeof a);        int n,m;        scanf("%d %d",&n,&m);        for(int i=0; i<n; i++)            scanf("%d",&a[i]);        ans=0;        for(int i=0; i<n; i++)        {            int left=1,right=1;            for(int j=i-1; j>=0; j--)            {                if(left>m)                    break;                if(a[j]>a[i])                    l[left++]=i-j;            }            if(left<=m)l[left]=i+1;            for(int j=i+1; j<n; j++)            {                if(right>m)                    break;                if(a[j]>a[i])                    r[right++]=j-i;            }            if(right<=m)r[right]=n-i;            for(int j=0; j<left; j++)            {                if(right+j<m)                    continue;                int lsum=l[j+1]-l[j];                int rsum=r[m-j]-r[m-j-1];                ans+=(long long)a[i]*lsum*rsum;            }        }        printf("%lld\n",ans);    }}
原创粉丝点击