80分,权值可持久化线段树疑似被卡常求大佬帮助
查看原帖
80分,权值可持久化线段树疑似被卡常求大佬帮助
378403
wanglexi31楼主2025/1/23 19:22
#include<bits/stdc++.h>
#define ll long long 
#define pb emplace_back
#define pii pair<int,int>
#define fir first
#define sec second
#define mod (998244353ll)
using namespace std;
int n,m,a[200005],b[200005]; 
const int N=200005,M=N,len=N*4+(int)ceil(log2(N))*M+5;
inline int read(){
	int x=0,f=1;
	char ch=getchar_unlocked();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar_unlocked();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar_unlocked();}
	return x*f;
}//_unlocked
inline int write(int x){
	if(x>=10)write(x/10);
	putchar_unlocked(x%10+'0');
}
struct PST{
//	int 
	int ls[len],rs[len],L[len],R[len],val[len],hd[M+5],cntloc,cntnode;
	void pushup(int x){
		val[x]=val[ls[x]]+val[rs[x]];
	}
	PST(){cntloc=0,cntnode=0,hd[0]=1;}
	void build(int l,int r){
//		Sleep(500);
		cntnode++;
//		cout<<"build "<<cntnode<<" "<<l<<" "<<r<<"\n";
		L[cntnode]=l,R[cntnode]=r;
//		cout<<"L["<<cntnode<<"]="<<l<<" R["<<cntnode<<"]="<<r<<"\n";
		if(l==r){
			ls[cntnode]=rs[cntnode]=-1;
			val[cntnode]=0;
			return;
		}
		int mid=l+r>>1;
		int p=cntnode;
		ls[p]=cntnode+1;
		build(l,mid);
		rs[p]=cntnode+1;
		build(mid+1,r);
	}
	void add(int x,int p,int k){
//		cout<<"add "<<x<<" "<<p<<" "<<k<<"\n";
//		cout<<"add "<<x<<" "<<p<<" "<<k<<"\n";
		int mid=L[x]+R[x]>>1;
		cntnode++;
		L[cntnode]=L[x];
		R[cntnode]=R[x];
		val[cntnode]=val[x];
		int pu=cntnode;
//		cout<<cntnode<<":"<<L[cntnode]<<"~"<<R[cntnode]<<" val="<<val[cntnode]<<"\n";
		if(L[x]==R[x]){
			ls[cntnode]=-1,rs[cntnode]=-1;
			val[cntnode]+=k;
//			cout<<cntnode<<"+1!!\n";
			return;
		}
		if(p<=mid)ls[cntnode]=cntnode+1,rs[cntnode]=rs[x]/*,cout<<"gotol "<<x<<":"<<ls[x]<<"\n"*/,add(ls[x],p,k);
		else /*cout<<"gotor "<<x<<":"<<rs[x]<<"\n",*/ls[cntnode]=ls[x],rs[cntnode]=cntnode+1,add(rs[x],p,k);
		pushup(pu);
//		cout<<"pushup "<<pu<<" val="<<val[pu]<<"\n";
	}
	void upd(int loc,int p,int k){
		cntloc++;
		hd[cntloc]=cntnode+1;
		add(hd[loc],p,k);
	}
	int query(int x,int l,int r){
//		cout<<"que "<<x<<" "<<l<<" "<<r<<" ";
		if(l<=L[x]&&R[x]<=r)return val[x];
		int mid=L[x]+R[x]>>1,ans=0;
		if(l<=mid)ans+=query(ls[x],l,r);
		if(r>=mid+1)ans+=query(rs[x],l,r);
		return ans;
	}
	int ask(int loc,int l,int r){
//		cout<<"ask:"<<loc<<" "<<p<<"\n";
//		cntloc++;cntnode++;
////		cout<<"aks "<<cntloc<<" "<<cntnode<<" "<<loc<<" "<<hd[loc]<<"\n";
//		hd[cntloc]=cntnode;
//		L[cntnode]=L[hd[loc]];
//		R[cntnode]=R[hd[loc]];
//		ls[cntnode]=ls[hd[loc]];
//		rs[cntnode]=rs[hd[loc]];
//		val[cntnode]=val[hd[loc]];
//		pushup(cntnode);
//cout<<loc<<" "<<hd[loc]<<"\n";
		int ans=query(hd[loc],l,r);
//		cout<<"ask:"<<loc<<" "<<l<<"~"<<r<<":"<<ans<<"\n";
		return ans;
	}
	void output(){
		cout<<"cntnode="<<cntnode<<" cntloc="<<cntloc<<"\n";
		for(int i=1;i<=cntnode;i++){
			cout<<"L["<<i<<"]="<<L[i]<<" R["<<i<<"]="<<R[i]<<" ls["<<i<<"]="<<ls[i]<<" rs["<<i<<"]="<<rs[i]<<" val["<<i<<"]="<<val[i]<<"\n";
			
		}for(int i=0;i<=cntloc;i++){
			cout<<"hd["<<i<<"]="<<hd[i]<<"\n";
		}
	}
}pst;
int main(){
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
	n=read();m=read();
	for(int i=1;i<=n;i++)a[i]=read(),b[i]=a[i];
	pst.build(1,n);
	sort(b+1,b+n+1);b[0]=-1;
	int kkk=0;
	for(int i=1;i<=n;i++)
		if(b[i]!=b[i-1])b[++kkk]=b[i];
	for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+kkk+1,a[i])-b;
	for(int i=1;i<=n;i++){
		pst.upd(i-1,a[i],1);
//		cout<<"\n";
	}
//	pst.output();
	while(m--){
		int l=read(),r=read(),k=read();
		//至少k个数<=mid mid最小
		int lef=0,rig=kkk;//lef:0 rig:1
		while(lef+1<rig){
			int mid=lef+rig>>1;
			int cnt=pst.ask(r,1,mid)-pst.ask(l-1,1,mid);
//			cout<<mid<<" "<<cnt<<"\n";
			if(cnt>=k)rig=mid;
			else lef=mid;
		} 
		write(b[rig]);
		puts("");
//		cout<<b[rig]<<"\n";
	}
	return 0;
}

求助卡常(复杂度应该是对的吧)

2025/1/23 19:22
加载中...