优先队列O2过了
查看原帖
优先队列O2过了
658786
STUDENT00楼主2022/11/20 17:39

闲来无事,水水主席树。发现只要求第8大,用什么?对了,用线段树+优先队列。时间复杂度一算,没问题。开完O2后提交,额,AC了。

#include<bits/stdc++.h>
#define pq priority_queue<int,vector<int>,greater<int> >
#define N 100010
using namespace std;
int n,m;
pq tree[N<<2];
void push_up(int rt){
	while(!tree[rt].empty()) tree[rt].pop();
	pq t=tree[rt<<1];
	while(!t.empty()){
		tree[rt].push(t.top());
		t.pop();
	}
	t=tree[rt<<1|1];
	while(!t.empty()){
		tree[rt].push(t.top());
		t.pop(); 
	}
	while(tree[rt].size()>8) tree[rt].pop();
}
void update(int l,int r,int rt,int a,int b){
	if(l==r){
		if(!tree[rt].empty()) tree[rt].pop();
		tree[rt].push(b);
		return;
	}
	int mid=l+r>>1;
	if(a<=mid) update(l,mid,rt<<1,a,b);
	else update(mid+1,r,rt<<1|1,a,b);
	push_up(rt);
}
pq query(int l,int r,int rt,int a,int b){
	if(a<=l&&b>=r) return tree[rt];
	int mid=l+r>>1;
	pq ans,t;
	if(a<=mid){
		t=query(l,mid,rt<<1,a,b);
		while(!t.empty()){
			ans.push(t.top());
			t.pop();
		}
	}
	if(b>mid){
		t=query(mid+1,r,rt<<1|1,a,b);
		while(!t.empty()){
			ans.push(t.top());
			t.pop();
		}
	}
	while(ans.size()>8) ans.pop();
	return ans;
}
int main(){
	scanf("%d%d",&n,&m);
	while(m--){
		char c[1];
		scanf("%s",c);
		if(c[0]=='C'){
			int p,x;
			scanf("%d%d",&p,&x);
			update(1,n,1,p,x);
		}else{
			int a,b;
			scanf("%d%d",&a,&b);
			pq ans=query(1,n,1,a,b);
			if(ans.size()<8) printf("0\n");
			else printf("%d\n",ans.top());
		}
	}
	return 0;
}
2022/11/20 17:39
加载中...