通过这题学会了维护链表,原来可以这么方便的算出某个值作为区间第K大的区间总数。。。
换句话说就是暂时不会用链表干别的←_←
#include<bits/stdc++.h> //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; #define ll long long #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) const int inf=0x3f3f3f3f; const int maxn=5e5+9; int n,k; int arr[maxn]; int pos[maxn]; int pre[maxn],nex[maxn]; int num1[maxn],num2[maxn]; ll solve(int x){ int x1=0,x2=0; for(int i=x;i &&x1<=k;i=pre[i])num1[++x1]=i-pre[i]; for(int i=x;i<=n&&x2<=k;i=nex[i])num2[++x2]=nex[i]-i; ll ans=0; for(int i=1;i<=x1;i++){ if(k-i+1<=x2 && k-i>=0)ans+=num1[i]*num2[k-i+1]; } return ans; } void del(int x){ pre[nex[x]]=pre[x];nex[pre[x]]=nex[x]; } int main(){ int T;scanf("%d",&T); while(T--){ scanf("%d%d",&n,&k); FOR(n){scanf("%d",&arr[i]);pos[arr[i]]=i;} for(int i=0;i<=n+1;i++){ pre[i]=i-1;nex[i]=i+1; } pre[0]=0; nex[n+1]=n+1; ll ans=0; FOR(n){ ans+=solve(pos[i])*i; del(pos[i]); } printf("%lld ",ans); } }