Kanade's sum 2017多校#3 链表

通过这题学会了维护链表,原来可以这么方便的算出某个值作为区间第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);
	}
}


原文地址:https://www.cnblogs.com/Drenight/p/8611292.html