萌新刚学 OI,求助入门题,悬赏关注!!!
  • 板块灌水区
  • 楼主Brainless_zxc
  • 当前回复23
  • 已保存回复23
  • 发布时间2024/8/24 15:52
  • 上次更新2024/8/24 16:08:22
查看原帖
萌新刚学 OI,求助入门题,悬赏关注!!!
661274
Brainless_zxc楼主2024/8/24 15:52

入门题P3380 40pts WA

代码简短易懂,相信各位实力惊人得大佬都看得懂并 1ms 调完,谢谢了!!!

哎听 xft 说300行往上的代码没人调,我这次放个 400 行的是不是有人调了/qd/qd/qd

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline long long lev(long long x){
	if(x){
		return 32-__builtin_clz(x);
	}
	else{
		return 1;
	}
}
inline pair<int,int>lca(int u,int v){
	if(u==v){
		return make_pair(u,v);
	}
	int log_len=32-__builtin_clz(u^v);
	int len=1<<log_len;
	int l=(u>>log_len)<<log_len;
	return make_pair(l,l|(len-1));
}
namespace seg_y{
	long long log_interval_y,cnt;
	struct node_y{
		int ch[2],l,r,sum;
	}tree[12000005];
	inline long long new_node(){
		return ++cnt;
	}
	inline void init(int x){
		log_interval_y=x;
		cnt=0;
		return;
	}
	inline long long new_root(){
		int ret=new_node();
		tree[ret].l=0;
		tree[ret].r=(1<<log_interval_y)-1;
		tree[ret].sum=0;
		return ret;
	}
	inline void push_up(int u){
		tree[u].sum=tree[tree[u].ch[0]].sum+tree[tree[u].ch[1]].sum;
		return;
	}
	inline bool handle(int u,int son,int pos,int val){
		bool ret=1;
		if(tree[u].ch[son]==0){
			int v=new_node();
			tree[u].ch[son]=v;
			tree[v].sum=val;
			tree[v].l=pos;
			tree[v].r=pos;
			push_up(u);
		}
		else if(tree[tree[u].ch[son]].l==tree[tree[u].ch[son]].r){
			if(tree[tree[u].ch[son]].l==pos){
				tree[tree[u].ch[son]].sum=val;
				push_up(u);
			}
			else{
				pair<int,int>_lca=lca(pos,tree[tree[u].ch[son]].l);
				int f=new_node();
				tree[f].l=_lca.first;
				tree[f].r=_lca.second;
				int v=new_node();
				tree[v].sum=val;
				tree[v].l=pos;
				tree[v].r=pos;
				if(pos<tree[tree[u].ch[son]].l){
					tree[f].ch[0]=v;
				}
				else{
					tree[f].ch[0]=tree[u].ch[son];
				}
				tree[f].ch[1]=(v^tree[u].ch[son])^tree[f].ch[0];
				tree[u].ch[son]=f;
				push_up(f);
				push_up(u);
			}
		}
		else if(pos<tree[tree[u].ch[son]].l||pos>tree[tree[u].ch[son]].r){
			pair<int,int>_lca=lca(pos,tree[tree[u].ch[son]].l);
			int f=new_node();
			tree[f].l=_lca.first;
			tree[f].r=_lca.second;
			int v=new_node();
			tree[v].sum=val;
			tree[v].l=pos;
			tree[v].r=pos;
			if(pos<tree[tree[u].ch[son]].l){
				tree[f].ch[0]=v;
			}
			else{
				tree[f].ch[0]=tree[u].ch[son];
			}
			tree[f].ch[1]=(v^tree[u].ch[son])^tree[f].ch[0];
			tree[u].ch[son]=f;
			push_up(f);
			push_up(u);
		}
		else{
			ret=0;
		}
		return ret;
	}
	inline void _set(int u,int pos,int val){
		int mid=(tree[u].l+tree[u].r)/2;
		if(pos<=mid){
			bool ret=handle(u,0,pos,val);
			if(ret==0){
				_set(tree[u].ch[0],pos,val);
				push_up(u);
			}
		}
		else{
			bool ret=handle(u,1,pos,val);
			if(ret==0){
				_set(tree[u].ch[1],pos,val);
				push_up(u);
			}
		}
		return;
	}
	inline long long _query(int u,int l,int r){
		if(u==0){
			return 0;
		}
		int L=tree[u].l;
		int R=tree[u].r;
		if(L>r||R<l){
			return 0;
		}
		if(l<=L&&R<=r){
			return tree[u].sum;
		}
		return _query(tree[u].ch[0],l,r)+_query(tree[u].ch[1],l,r);
	}
	inline long long find_pos(int u,int pos){
		while(u){
			if(tree[u].r<pos||tree[u].l>pos){
				return 0;
			}
			if(tree[u].l==tree[u].r){
				break;
			}
			int mid=(tree[u].l+tree[u].r)/2;
			u=tree[u].ch[pos>mid];
		}
		return u;
	}
	inline long long clone(int u){
		int ret=new_node();
		tree[ret].l=tree[u].l;
		tree[ret].r=tree[u].r;
		tree[ret].sum=tree[u].sum;
		if(tree[u].ch[0]){
			tree[ret].ch[0]=clone(tree[u].ch[0]);
		}
		else{
			tree[ret].ch[0]=0;
		}
		if(tree[u].ch[1]){
			tree[ret].ch[1]=clone(tree[u].ch[1]);
		}
		else{
			tree[ret].ch[1]=0;
		}
		return ret;
	}
}
namespace seg_x{
	long long log_interval_x;
	struct node_x{
		int ch[2],l,r,rt;
	}tree[200005];
    int cnt,root;
	inline long long new_node(){
		return ++cnt;
	}
	inline void init(int x){
		log_interval_x=x;
		cnt=0;
		root=new_node();
		tree[root].l=0;
		tree[root].r=(1<<log_interval_x)-1;
		tree[root].rt=seg_y::new_root();
	}
	inline void push_up(int u,int y){
		int lcpos=seg_y::find_pos(tree[tree[u].ch[0]].rt,y);
		int rcpos=seg_y::find_pos(tree[tree[u].ch[1]].rt,y);
		int res=seg_y::tree[lcpos].sum+seg_y::tree[rcpos].sum;
		seg_y::_set(tree[u].rt,y,res);
		return;
	}
	inline bool handle(int u,int son,int x,int y,int val){
		bool ret=1;
    	if(tree[u].ch[son]==0){
    		int v=new_node();
    		tree[u].ch[son]=v;
    		tree[v].l=x;
    		tree[v].r=x;
    		tree[v].rt=seg_y::new_root();
    		seg_y::_set(tree[v].rt,y,val);
    		push_up(u,y);
		}
		else if(tree[tree[u].ch[son]].l==tree[tree[u].ch[son]].r){
			if(tree[tree[u].ch[son]].l==x){
				seg_y::_set(tree[tree[u].ch[son]].rt,y,val);
				push_up(u,y);
			}
			else{
				pair<int,int>_lca=lca(x,tree[tree[u].ch[son]].l);
				int f=new_node();
				tree[f].l=_lca.first;
				tree[f].r=_lca.second;
				tree[f].rt=seg_y::clone(tree[tree[u].ch[son]].rt);
				int v=new_node();
				tree[v].l=x;
				tree[v].r=x;
				tree[v].rt=seg_y::new_root();
				seg_y::_set(tree[v].rt,y,val);
				if(x<tree[tree[u].ch[son]].l){
					tree[f].ch[0]=v;
				}
				else{
					tree[f].ch[0]=tree[u].ch[son];
				}
				tree[f].ch[1]=(v^tree[u].ch[son])^tree[f].ch[0];
				tree[u].ch[son]=f;
				push_up(f,y);
				push_up(u,y);
			}
		}
		else if(x<tree[tree[u].ch[son]].l||x>tree[tree[u].ch[son]].r){
			pair<int,int>_lca=lca(x,tree[tree[u].ch[son]].l);
			int f=new_node();
			tree[f].l=_lca.first;
			tree[f].r=_lca.second;
			tree[f].rt=seg_y::clone(tree[tree[u].ch[son]].rt);
			int v=new_node();
			tree[v].l=x;
			tree[v].r=x;;
			tree[v].rt=seg_y::new_root();
			seg_y::_set(tree[v].rt,y,val);
			if(x<tree[tree[u].ch[son]].l){
				tree[f].ch[0]=v;
			}
			else{
				tree[f].ch[0]=tree[u].ch[son];
			}
			tree[f].ch[1]=(v^tree[u].ch[son])^tree[f].ch[0];
			tree[u].ch[son]=f;
			push_up(f,y);
			push_up(u,y);
		}
		else{
			ret=0;
		}
		return ret;
	}
	inline void _set(int u,int x,int y,int val){
		int mid=(tree[u].l+tree[u].r)/2;
		if(x<=mid){
			bool ret=handle(u,0,x,y,val);
			if(ret==0){
				_set(tree[u].ch[0],x,y,val);
				push_up(u,y);
			}
		}
		else{
			bool ret=handle(u,1,x,y,val);
			if(ret==0){
				_set(tree[u].ch[1],x,y,val);
				push_up(u,y);
			}
		}
		return;
	}
	inline void set(int x,int y,int val){
		_set(root,x,y,val);
		return;
	}
    inline long long _query(int u,int xl,int xr,int yl,int yr){
    	if(u==0){
    		return 0;
		}
		int L=tree[u].l;
		int R=tree[u].r;
		if(L>xr||R<xl){
			return 0;
		}
		if(xl<=L&&R<=xr){
			return seg_y::_query(tree[u].rt,yl,yr);
		}
		return _query(tree[u].ch[0],xl,xr,yl,yr)+_query(tree[u].ch[1],xl,xr,yl,yr);
	}
    inline long long query(int xl,int xr,int yl,int yr){
    	return _query(root,xl,xr,yl,yr);
	}
    inline long long find_kth(int rk,int yl,int yr){
    	int u=root;
    	if(tree[u].ch[0]==0||tree[u].ch[1]==0){
    		u=tree[u].ch[!tree[u].ch[0]];
		}
		while(tree[u].ch[0]&&tree[u].ch[1]){
			int lcsum=seg_y::_query(tree[tree[u].ch[0]].rt,yl,yr);
			if(lcsum>=rk){
				u=tree[u].ch[0];
			}
			else{
				rk-=lcsum;
				u=tree[u].ch[1];
			}
		}
		return tree[u].l;
	}
}
int n,m,op;
int l,r,pos,k;
int a[100005];
inline void init(int x,int y){
	seg_y::init(lev(y));
	seg_x::init(lev(x));
	return;
}
inline void add(int x,int y,int val){
	seg_x::set(x,y,val+seg_x::query(x,x,y,y));
}
inline void arr_set(int pos,int val){
	a[pos]=val;
	add(val,pos,1);
	return;
}
inline void update(int pos,int val){
	add(a[pos],pos,-1);
	add(val,pos,1);
	a[pos]=val;
	return;
}
inline long long get_rk(long long l,long long r,long long k){
	return seg_x::query(0,k-1,l,r)+1;
}
inline long long find_kth(long long l,long long r,long long k){
	return seg_x::find_kth(k,l,r);
}
inline long long min_element(long long l,long long r){
	return find_kth(l,r,1);
}
inline long long max_element(long long l,long long r){
	return find_kth(l,r,r-l+1);
}
inline long long prec(long long l,long long r,long long k){
	if(k<=min_element(l,r)){
		return -INT_MAX;
	}
	else{
		return find_kth(l,r,get_rk(l,r,k)-1);
	}
}
inline long long succ(long long l,long long r,long long k){
	if(k>=max_element(l,r)){
		return INT_MAX;
	}
	else{
		return find_kth(l,r,get_rk(l,r,k+1));
	}
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	init(1000000000,n);
	for(int i=1;i<=n;i++){
		int x;
		cin>>x;
		arr_set(i,x);
	}
	while(m--){
		cin>>op;
		if(op==1){
			cin>>l>>r>>k;
			cout<<get_rk(l,r,k)<<'\n';
		}
		else if(op==2){
			cin>>l>>r>>k;
			cout<<find_kth(l,r,k)<<'\n';
		}
		else if(op==3){
			cin>>pos>>k;
			update(pos,k);
		}
		else if(op==4){
			cin>>l>>r>>k;
			cout<<prec(l,k,r)<<'\n';
		}
		else{
			cin>>l>>r>>k;
			cout<<succ(l,r,k)<<'\n';
		}
	}
}
2024/8/24 15:52
加载中...