Let f(l,r,k)
Specially , f(l,r,k)=0
Give you k
There are T test cases.
1≤T≤10
k≤min(n,80)
A[1..n] is a permutation of [1..n]
∑n≤5∗10
For each test case,there are only two integers n
1 5 2 1 2 3 4 5
30
题目大意:把一个数组分成若干子部分,求每部分中第k大的数的和是多少?
比较详细的解释:点击打开链接
#include <iostream> #include <bits/stdc++.h> using namespace std; int a[500005],lef[500005],righ[500005]; typedef long long ll; int main() { int T; scanf("%d",&T); while(T--) { int n,k,x; scanf("%d%d",&n,&k); for(int i=1; i<=n; i++) { scanf("%d",&x); a[x]=i; lef[i]=0; righ[i]=n+1; } set<int>s; set<int>::iterator ite; lef[n+1]=0; righ[n+1]=n+1; s.insert(0); s.insert(n+1); ll ans=0; int r; for(int i=n; i>0; i--) { s.insert(a[i]); ite=s.find(a[i]); ite++; r=*ite; int l=lef[r]; lef[r]=a[i]; righ[a[i]]=r; righ[l]=a[i]; lef[a[i]]=l; if(n-i+1<k) continue; int nowl=a[i]; for(int j=1; j<=k&&nowl; j++) nowl=lef[nowl]; int nowr=nowl; for(int j=1; j<=k&&nowr!=n+1; j++) nowr=righ[nowr]; for(int j=1; j<=k; j++) { if(nowl==a[i]||nowr==n+1) break; int nextl=righ[nowl]; int nextr=righ[nowr]; ans+=(ll)(nextl-nowl)*(nextr-nowr)*i; // cout<<ans<<" "; //cout<<"_____________"<<endl; nowl=nextl; nowr=nextr; } } printf("%lld\n",ans); } return 0; }
本文介绍了一种算法,用于解决给定数组中所有子数组的第K大元素之和的问题。通过构建特殊的数据结构,实现了高效的计算。
969

被折叠的 条评论
为什么被折叠?



