【学习笔记】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