HDU 6058 Kanade's sum —— 2017 Multi-University Training 3

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 6058 Kanade's sum —— 2017 Multi-University Training 3相关的知识,希望对你有一定的参考价值。

Kanade‘s sum

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

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 r?l+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]

n5?105
 
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
1
5 2
1 2 3 4 5
 
Sample Output
30
 
题目大意:给定数列A,A是1,2,...,n的一个排序,求数列中所有区间的第k小的数之和。
思路:对于1~n的某个数 i,向左向右分别数出 k 个比 i 大的数,求得第 k 小的数是 i 的最大区间。然后在这个最大区间里,从左往右每次取k个不小于 i 的数,每一次更新区间时加上前后两个区间的差值即可。
 
AC代码(借鉴了下网上的代码):
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<vector>
 5 #include<algorithm>
 6 #include<fstream> 
 7 using namespace std;
 8 int a[500005];
 9 long long l[90], r[90];
10 int main()
11 {
12     int T,n,k;
13     //ifstream cin("ylq.txt");
14     cin>>T; 
15     while(T--)
16     {
17         scanf("%d %d", &n, &k);
18         //cin>>n>>k;
19         for(int i=1;i<=n;i++) scanf("%d", &a[i]);
20         int t;
21         long long ans=0;
22         for(int i=1;i<=n;i++){
23             t=0;
24             l[t++]=i;
25             int j;
26             for(j=i-1;j>0&&t<k;j--){
27                 if(a[j]>a[i]){
28                     l[t++]=j;
29                 }
30             }
31             long long sum=0;
32             if(t==k)
33             {
34                 int tmp=1;
35                 for(;j>0;j--){
36                     if(a[j]<a[i]) tmp++;
37                     else break;
38                 }
39                 sum+=tmp;
40                 for(j=i+1;j<=n&&t>=0;j++){
41                     if(a[j]<a[i]) sum+=tmp;
42                     else{
43                         t--;
44                         if(t==0) break;
45                         tmp=l[t-1]-l[t];
46                         sum+=tmp;
47                     }
48                 }
49             }
50             else
51             {
52                 for(j=i+1;j<=n&&t<k;j++){
53                     if(a[j]>a[i]) l[t++]=j;
54                 }
55                 if(t==k)
56                 {
57                     sort(l, l+t);
58                     int tmp=l[0];
59                     int p=0;
60                     sum+=tmp;
61                     for(;j<=n&&p<t;j++){
62                         if(a[j]<a[i]) sum+=tmp;
63                         else{
64                             p++;
65                             if(l[p]>i) break;    
66                             tmp=abs(l[p]-l[p-1]);
67                             sum+=tmp;
68                         }
69                         
70                     }
71                 }
72             }
73             ans+=(long long)(sum*a[i]);
74         } 
75         cout<<ans<<endl;
76     }
77 }

 

 

以上是关于HDU 6058 Kanade's sum —— 2017 Multi-University Training 3的主要内容,如果未能解决你的问题,请参考以下文章

HDU 6058 Kanade's sum —— 2017 Multi-University Training 3

链表2017多校训练3 HDU 6058 Kanade's sum

6058 Kanade's sum ????????????()

HDU-6057 Kanade's convolution

hdu6059 Kanade's trio 字典树+容斥

HDU 6057 Kanade's convolution