【HDU 6058 Kanade's sum】+ 链表

本文介绍了一个名为Kanade’ssum的问题解决方案,该问题要求对于给定数组A[1..n],找到所有子数组中第k大的元素出现次数,并通过一个高效的算法实现。代码使用了C++编写,涉及数组操作、数据结构应用等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Kanade’s sum

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

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

#include<cstdio>
const int MAX = 5e5 + 10;
typedef long long LL;
int N,k,a[MAX],p[MAX],n[MAX],l[82],r[82];
LL sl(int x){
    int nl = 0,nr = 0;
    for(int i = x; i && nl < k; i = p[i]) l[++nl] = i - p[i]; // 第 nl - 1 比查找的数大的数 ~ 第 nl 比查找的数大的数的区间里的数的个数
    for(int i = x; i <= N && nr < k; i = n[i]) r[++nr] = n[i] - i;
    LL sum = 0;
    for(int i = 1; i <= nl;  i++)
        if(k - i + 1 <= nr)
            sum += (LL) l[i] * r[k - i + 1];
    return sum;
}
int main()
{
    int T,b;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&N,&k);
        for(int i = 1; i <= N; i++)
            scanf("%d",&b),a[b] = i;
        for(int i = 1; i <= N; i++) p[i] = i - 1,n[i] = i + 1;
        LL ans = 0;
        for(int i = 1; i <= N; i++){
            ans += (LL)sl(a[i]) * i;
            p[n[a[i]]] = p[a[i]],n[p[a[i]]] = n[a[i]]; // 删除
        }
        printf("%lld\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值