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
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]
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; }