HDU 6058 Kanade's sum (技巧)
2017-08-10 10:54
381 查看
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=1∑nr=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]
∑n≤5∗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
题意
给出n和
k,求
1~n排列中每个区间的第
k大数的总和是多少,区间长度小于
k时贡献为
0。
思路
考虑枚举包含某个数字且其为第k大数的区间有多少个,我们只需要找出它左边最近的
k个比它大的和右边最近的
k个比它大的,然后就可以计算出该数字对最终结果的贡献。
可以从小到大枚举每个数字
x,维护一个链表,链表里只有
> = x的数,在得出该数的结果后删除
x可以使得链表长度减少,从而优化时间。
AC 代码
#include<bits/stdc++.h> using namespace std; typedef __int64 LL; const int maxn = 5e5+10; int a[maxn]; int pre[maxn]; int nex[maxn]; int wei[maxn]; int stk1[85]; int stk2[85]; int top1,top2; int main() { int T; scanf("%d",&T); while(T--) { int n,k; scanf("%d%d",&n,&k); for(int i=1; i<=n; i++) { scanf("%d",a+i); wei[a[i]]=i; pre[i]=i-1; nex[i]=i+1; } pre[0]=-1,nex[n+1]=n+2; LL ans=0; for(int i=1; i<=n; i++) { int x=wei[i]; top1=top2=0; for(int j=x; j>=0&&top1<=k; j=pre[j]) stk1[++top1]=j; for(int j=x; j<=n+1&&top2<=k; j=nex[j]) stk2[++top2]=j; for(int j=k-top2+2; j<=top1-1; j++) ans+=LL(stk1[j]-stk1[j+1])*LL(stk2[k-j+2]-stk2[k-j+1])*i; nex[pre[x]]=nex[x]; pre[nex[x]]=pre[x]; } printf("%I64d\n",ans); } return 0; }
相关文章推荐
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- hdu 6058 Kanade's sum(模拟)
- HDU 6058 Kanade's sum (链表, 2017 Multi-Univ Training Contest 3)
- hdu 6058 Kanade's sum
- HDU 6058 Kanade's sum(链表)
- HDU 6058 Kanade's sum (链表)
- HDU-6058 Kanade's sum
- hdu 6058 Kanade's sum 维护链表
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- HDU 6058 Kanade's sum (区间第k大的数的贡献)
- 17 多校 3 - 1003 - Kanade's sum (HDU 6058)
- Kanade's sum(hdu 6058)
- HDU 2017 多校联合训练赛3 3003 6058 Kanade's sum 枚举 模拟链表
- 2017 多校训练第三场 HDU 6058 Kanade's sum
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- hdu 6058 Kanade's sum
- hdu 6058 Kanade's sum
- (2017多校训练第三场)HDU - 6058 Kanade's sum 链表
- 【多校训练】hdu 6058 Kanade's sum