稀烂的模版求调
查看原帖
稀烂的模版求调
835809
T_TLucas_Yin楼主2024/3/15 20:40
//false代码
#include<bits/stdc++.h>
using namespace std;
struct node{
	int x,k;
}a[1000005];
bool cmp(node a,node b){
	return a.x<b.x;
}
int n,m,p,b[1000005],c[1000005],l,r,k;
int root[6000005],tot,top;
int f[6000005],ls[6000005],rs[6000005],flag[6000005];
void build(int &root,int l,int r){//此时的root要引用,辅助初始化第一次传进来的根和每个节点的左右子树根
	root=++top,flag[root]=0;
	if(l==r){ f[root]=0;return; }
	int mid=(l+r)>>1;
	build(ls[root],l,mid);
	build(rs[root],mid+1,r);
	f[root]=f[ls[root]]+f[rs[root]];
}
void cpy(int roota,int rootb){
	ls[rootb]=ls[roota];
	rs[rootb]=rs[roota];
	f[rootb]=f[roota];
	flag[rootb]=flag[roota];
}
void update(int &root,int lroot,int l,int r,int fl,int fr,int x){//区间修改
	root=++top,cpy(lroot,root);
	f[root]+=x*(fr-fl+1);//给包含修改区间的节点加整个修改区间的x
	if(fl==l&&r==fr){ flag[root]+=x;return; } //到完全契合的节点再放懒标记
	int mid=(l+r)>>1;
	if(fr<=mid) update(ls[root],ls[root],l,mid,fl,fr,x);//整个区间在左子树上
	else if(fl>mid) update(rs[root],rs[root],mid+1,r,fl,fr,x);//整个区间在右子树上
	else{//区间包含mid
		update(ls[root],ls[root],l,mid,fl,mid,x);
		update(rs[root],rs[root],mid+1,r,mid+1,fr,x);
	}
}
int Find(int root,int l,int r,int fl,int fr){
	if(fl<=l&&r<=fr) return f[root];
	int mid=(l+r)>>1,sum=flag[root]*(fr-fl+1);//未传完的懒标记直接加到sum里
	if(fr<=mid) return sum+Find(ls[root],l,mid,fl,fr);
	else if(l>mid) return sum+Find(rs[root],mid+1,r,fl,fr);
	else return sum+Find(ls[root],l,mid,fl,mid)+Find(rs[root],mid+1,r,mid+1,fr);//修改区间与左右子树的三种关系
}
int Findk(int roota,int rootb,int l,int r,int k){
	if(l==r) return l;
	int mid=(l+r)>>1;
	if(k<=f[ls[rootb]]-f[ls[roota]]/*要查找的区间*/) return Findk(ls[roota],ls[rootb],l,mid,k);
	else return Findk(rs[roota],rs[rootb],mid+1,r,k-(f[ls[rootb]]-f[ls[roota]]));//直接查找
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){ cin>>a[i].x;a[i].k=i; }
	sort(a+1,a+1+n,cmp),p=b[a[1].k]=1,c[p]=a[1].x;
	for(int i=2;i<=n;i++){
		if(a[i].x==a[i-1].x) b[a[i].k]=p,c[p]=a[i].x;
		else p++,b[a[i].k]=p,c[p]=a[i].x;
	}
	build(root[++tot],1,p);
	for(int i=1;i<=n;i++) tot++,update(root[tot],root[tot-1],1,p,b[i],b[i],1);
	for(int i=1;i<=m;i++){
		cin>>l>>r>>k;
		cout<<Findk(root[l-1],root[r],1,p,k)<<"\n";
	}
	return 0;
}
2024/3/15 20:40
加载中...