[HDU]6058 Kanade's sum

来源:互联网 发布:seo零基础 编辑:程序博客网 时间:2024/06/07 00:25

http://acm.hdu.edu.cn/showproblem.php?pid=6058

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.

1≤T≤10

k≤min(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
1

5 2

1 2 3 4 5

Sample Output
30

题解

这是一道技巧性非常强的一道题

如果能想到从小枚举第k大的值的话这个题也就能AC了,因为比当前值小的数字对当前值的第k大无影响,我们要知道的是比当前值大的所在位置即可,利用链表保存数据,每次枚举完了对当前数字进行删除o(1),那么链表里存的永远是比当前值大的数,那么只要在当前数值的位置往链表两边枚举k个值得到位置即可,有了位置不难得到答案,复杂度 o(nk)

#pragma GCC optimize ("O2")#include<stdio.h>#include<vector>#include<algorithm>using namespace std;typedef long long LL;const int MAXS = 20 * 1024 * 1024;char buf[MAXS], *ch;inline void read(int &x) {    while(*ch <= 32) ++ch;    for(x = 0; *ch >= 48; ++ch) x = x * 10 + *ch - 48;}const int MAXN = 5e5 + 5;int pos[MAXN], par[MAXN], nxt[MAXN], n, k;int lst[85], rst[85], lsz, rsz;int main(){    fread(buf, MAXS, 1, stdin);    ch = buf;    int T, x;    read(T);    while(T--) {        read(n);        read(k);        for(int i = 1; i <= n; ++i) {            read(x);            pos[x] = i;            par[i] = i - 1;            nxt[i] = i + 1;        }        LL ans = 0;        for(int i = 1; i <= n; ++i) {            lsz = rsz = 0;            int it = pos[i];            while(0 < it && lsz < k) {                lst[lsz++] = it - par[it];                it = par[it];            }            it = pos[i];            while(it <= n && rsz < k) {                rst[rsz++] = nxt[it] - it;                it = nxt[it];            }            int lp = lsz - 1, rp = k - lsz;            while(rp < rsz && i + rp <= n) {                ans += 1LL * i * lst[lp--] * rst[rp++];            }            par[nxt[pos[i]]] = par[pos[i]];            nxt[par[pos[i]]] = nxt[pos[i]];        }        printf("%lld\n", ans);    }    return 0;}
原创粉丝点击