其他分享
首页 > 其他分享> > 【学习笔记】2021.10.6 - 清北学堂模拟赛

【学习笔记】2021.10.6 - 清北学堂模拟赛

作者:互联网

T1 区间第k大

Subtask1 50 pts

思路

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long ll;
const int MAXN(300233);
struct poi{
	int ls,rs,sum,lt;
}tree[MAXN<<5];
int cnt,p[MAXN],n,kkksc03,rt[MAXN],ans[MAXN],cha[MAXN];
inline int R(){
	int x=0;char c='c';
	while(c>'9'||c<'0') c=getchar();
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return x;
}
inline void BUILD(int OLD,int &NOW,int l,int r,int num){
	NOW=++cnt;
	tree[NOW].ls=tree[OLD].ls;
	tree[NOW].rs=tree[OLD].rs;
	tree[NOW].sum=tree[OLD].sum+1;
	if(l==r) return;
	int mid=(l+r)>>1;
	if(num<=mid) BUILD(tree[OLD].ls,tree[NOW].ls,l,mid,num);
	else BUILD(tree[OLD].rs,tree[NOW].rs,mid+1,r,num);
	return;
}
inline int QUERY(int L,int R,int l,int r,int k){
	if(l==r) return l;
	int lsum=tree[tree[R].ls].sum-tree[tree[L].ls].sum;
//	printf("l %d r %d mid %d k %d lsum %d Llssum %d Rlssum %d\n",l,r,(l+r)>>1,k,lsum,tree[tree[L].ls].sum,tree[tree[R].ls].sum);
	int mid=(l+r)>>1;
	if(k<=lsum) return QUERY(tree[L].ls,tree[R].ls,l,mid,k);
	else return QUERY(tree[L].rs,tree[R].rs,mid+1,r,k-lsum);
}
int main(){
//	freopen("ex_sequence3.in","r",stdin);
//	freopen("my.txt","w",stdout); 
	n=R();kkksc03=R();
	for(register int i=1;i<=n;++i) p[i]=R(),cha[p[i]]=i;
	for(register int i=1;i<=n;++i) BUILD(rt[i-1],rt[i],1,n,p[i]);
	for(register int i=1;i<=n-kkksc03+1;++i)
		for(register int j=i+kkksc03-1;j<=n;++j)
//		printf("QUE %d ~ %d:\n",i,j),
			ans[cha[QUERY(rt[i-1],rt[j],1,n,j-i-kkksc03+2)]]++;
	for(register int i=1;i<=n;++i) printf("%d ",ans[i]);
	printf("\n");
	return 0;
}
//打五把CS:GO! 

标签:long,2021.10,int,sum,tree,笔记,ls,清北,include
来源: https://www.cnblogs.com/Konjac-Binaries/p/15371157.html