HDU-Kanade's sum-模拟

来源:互联网 发布:java读取xml文件内容 编辑:程序博客网 时间:2024/06/06 18:34

Kanade's sum

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2799    Accepted Submission(s): 1155


Problem Description
Give you an array A[1..n]of length n

Let f(l,r,k) be the k-th largest element of A[l..r].

Specially , f(l,r,k)=0 if rl+1<k.

Give you k , you need to calculate nl=1nr=lf(l,r,k)

There are T test cases.

1T10

kmin(n,80)

A[1..n] is a permutation of [1..n]

n5105
 

Input
There is only one integer T on first line.

For each test case,there are only two integers n,k on first line,and the second line consists of n integers which means the array A[1..n]
 

Output
For each test case,output an integer, which means the answer.
 

Sample Input
15 21 2 3 4 5
 

Sample Output
30
 

解题思路
题意:算出数组[n]的所以子数组的第k大的总和
将大问题化成n的小问题,找到当前数被看做第k大的数的所有子数组(可以看成找到比当前位置之前大的k个数和当前位置之后的k个数,记录每个数的位置,可以找到中间比当前数小的个数)
 

解题代码
#include<iostream>#include<stdio.h>#include<string.h>using namespace std;int main(){    int T;    scanf("%d",&T);    int n,k;    int a[5*100001];    int aa[5*100001];    long long int ans;    while(T--)    {        memset(a,0x3f3f3f,sizeof(a));        ans=0;        scanf("%d%d",&n,&k);        for(int i=1;i<=n;i++)            scanf("%d",&a[i]);        for(int i=1;i<=n;i++)        {            int right=0;            int left=0;            for(int j=i+1;j<=n+1;j++)            {               if(a[j]>a[i])//在i位置后面比当前数大的               {                   right++;                   aa[k+right]=j;               }               if(right==k)               break;            }            for(int j=i-1;j>=0;j--)            {                if(a[j]>a[i])//在i位置前面比当前数大的                {                    left++;                    aa[k-left]=j;                }                if(left==k)                    break;            }            aa[k]=i;            int lnum,rnum;            for(int j=k+right-1;j>=k;j--)            {                if(j-k+1<k-left+1)                    break;                lnum=aa[j-k+1]-aa[j-k];                rnum=aa[j+1]-aa[j];                ans+=(long long int)(lnum*rnum)*a[i];            }        }        printf("%lld\n",ans);    }    return 0;}


原创粉丝点击