求助线段树套替罪羊树TLE
查看原帖
求助线段树套替罪羊树TLE
394373
Hanoist楼主2022/3/5 11:29

RT,#2不开O2TLE,开了跑得飞快,求dalao指点一下

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
	int x = 0,f = 1;
	char c = getchar();
	while(c < '0' || c > '9'){
		if(c == '-') f = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9'){
		x = (x << 3) + (x << 1) + (c ^ 48);
		c = getchar();
	}
	return x * f;
}
const int N = 2e5 + 1;
const int inf = 2147483647;
const double alpha = 0.75;
#define mid (l + r >> 1)
int n,m,a[N],rt[N],buc[N],tot,num;
struct yjx{
	int ls[N * 30],rs[N * 30],val[N * 30],cnt[N * 30],siz[N * 30];
	inline void pushup(int k){
		siz[k] = siz[ls[k]] + siz[rs[k]] + cnt[k];
	}
	inline bool unb(int k){
		return alpha * siz[k] < max(siz[ls[k]],siz[rs[k]]);
	}
	void extract(int k){
		if(ls[k]) extract(ls[k]);
		if(cnt[k]) buc[++num] = k;
		if(rs[k]) extract(rs[k]);
	}
	void build(int &k,int l,int r){
		if(l > r){
			k = 0;
			return;
		}
		k = buc[mid];
		build(ls[k],l,mid - 1);
		build(rs[k],mid + 1,r);
		pushup(k);
	}
	inline void rebuild(int &k){
		num = 0;
		extract(k);
		build(k,1,num);
	}
	void insert(int &k,int c){
		if(!k){
			k = ++tot;
			ls[k] = rs[k] = 0;
			val[k] = c;
			siz[k] = cnt[k] = 1;
			return;
		}
		if(val[k] == c){
			++cnt[k];
			pushup(k);
			return;
		}
		if(c < val[k]) insert(ls[k],c);
		else insert(rs[k],c);
		pushup(k);
		if(unb(k)) rebuild(k);
	}
	void del(int &k,int c){
		if(c == val[k]){
			--cnt[k];
			pushup(k);
			return;
		}
		if(c < val[k]) del(ls[k],c);
		else del(rs[k],c);
		pushup(k);
		if(unb(k)) rebuild(k);
	}
	void print(int k){
		if(ls[k]) print(ls[k]);
		printf("%d ",val[k]);
		if(rs[k]) print(rs[k]);
	}
	inline int query_rnk(int k,int c){
		int ret = 1;
		while(1){
			if(!k) return ret;
			if(c == val[k]) return ret + siz[ls[k]];
			if(c < val[k]){
				k = ls[k];
			}
			else{
				ret += siz[ls[k]] + cnt[k];
				k = rs[k];
			}
		}
	}
	inline int query_kth(int k,int c){
		while(1){
			if(!k){
				if(!c) return -inf;
				else return inf;
			}
			if(c > siz[ls[k]] && c <= siz[ls[k]] + cnt[k]) return val[k];
			if(c <= siz[ls[k]]){
				k = ls[k];
			}
			else{
				c -= siz[ls[k]] + cnt[k];
				k = rs[k];
			}
		}
	}
	inline int query_pre(int k,int c){
		int temp = query_rnk(k,c) - 1;
		return query_kth(k,temp);
	}
	inline int query_nxt(int k,int c){
		int temp = query_rnk(k,c + 1);
		return query_kth(k,temp);
	}
}bt;
struct wyx{
	void build(int k,int l,int r){
		for(int i = l;i <= r;i++) bt.insert(rt[k],a[i]);
		if(l == r) return;
		build(k << 1,l,mid);
		build(k << 1 | 1,mid + 1,r);
	}
	void modify(int k,int l,int r,int x,int c){
		bt.del(rt[k],a[x]);
		bt.insert(rt[k],c);
		if(l == r) return;
		if(x <= mid) modify(k << 1,l,mid,x,c);
		else modify(k << 1 | 1,mid + 1,r,x,c);
	}
	int query_rnk(int k,int l,int r,int x,int y,int c){
		if(x <= l && r <= y){
			return bt.query_rnk(rt[k],c);
		}
		int ret = 0;
		if(x <= mid) ret += query_rnk(k << 1,l,mid,x,y,c);
		if(y > mid) ret += query_rnk(k << 1 | 1,mid + 1,r,x,y,c);
		if(x <= mid && y > mid) --ret;
		return ret;
	}
	int query_kth(int x,int y,int c){
		int l = 0,r = 1e8;
		while(l < r){
			int Mid = (l + r + 1) >> 1;
			if(query_rnk(1,1,n,x,y,Mid) > c) r = Mid - 1;
			else l = Mid;
		}
		return l;
	}
	int query_pre(int k,int l,int r,int x,int y,int c){
		if(x <= l && r <= y){
			return bt.query_pre(rt[k],c);
		}
		int ret = -inf;
		if(x <= mid) ret = query_pre(k << 1,l,mid,x,y,c);
		if(y > mid) ret = max(ret,query_pre(k << 1 | 1,mid + 1,r,x,y,c));
		return ret;
	}
	int query_nxt(int k,int l,int r,int x,int y,int c){
		if(x <= l && r <= y){
			return bt.query_nxt(rt[k],c);
		}
		int ret = inf;
		if(x <= mid) ret = query_nxt(k << 1,l,mid,x,y,c);
		if(y > mid) ret = min(ret,query_nxt(k << 1 | 1,mid + 1,r,x,y,c));
		return ret;
	}
}str;
int main(){
	int i,x,y,w,opt;
	n = read(),m = read();
	for(i = 1;i <= n;i++){
		a[i] = read();
	}
	str.build(1,1,n);
	for(i = 1;i <= m;i++){
		opt = read();
		if(opt == 1){
			x = read(),y = read(),w = read();
			printf("%d\n",str.query_rnk(1,1,n,x,y,w));
		}
		if(opt == 2){
			x = read(),y = read(),w = read();
			printf("%d\n",str.query_kth(x,y,w));
		}
		if(opt == 3){
			x = read(),w = read();
			str.modify(1,1,n,x,w);
			a[x] = w;
		}
		if(opt == 4){
			x = read(),y = read(),w = read();
			printf("%d\n",str.query_pre(1,1,n,x,y,w));
		}
		if(opt == 5){
			x = read(),y = read(),w = read();
			printf("%d\n",str.query_nxt(1,1,n,x,y,w));
		}
	}
	return 0;
}
2022/3/5 11:29
加载中...