社区讨论

本人刚学OI 0s,不会平衡树会值域线段树求条

P3369【模板】普通平衡树参与者 8已保存回复 18

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
18 条
当前快照
1 份
快照标识符
@mkfhpoqq
此快照首次捕获于
2026/01/15 21:33
上个月
此快照最后确认于
2026/01/18 14:30
上个月
查看原帖
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
int tree[400005];
//tree[i]->i节点有多少个数
/*
以下全用操作名称+操作编号(多个连一起)
/的形式定义外部直接调用的函数
*/
void up(int p)
{
	tree[p]=tree[p*2]+tree[p*2+1];
}
void update12(int p,int l,int r,int x,int k)
{
	if(l==r)
	{
		tree[p]+=k;
		return;
	}
	int mid=(l+r)>>1;
	if(x<=mid) update12(p*2,l,mid,x,k);
	else update12(p*2+1,mid+1,r,x,k);
	up(p);
}
int query3(int p,int l,int r,int x) { // 返回<x的数的个数
    if(r < x) return tree[p]; // 整区间<x,返回总数
    if(l >= x) return 0;      // 整区间≥x,返回0
    int mid=(l+r)>>1;
    return query3(p*2,l,mid,x) + query3(p*2+1,mid+1,r,x); // 递归求和左右子树
}
int query4(int p,int l,int r,int x)
{
	if(l==r) return l;
	int mid=(l+r)>>1;
	if(tree[p*2]>=x) return query4(p*2,l,mid,x);
	else return query4(p*2+1,mid+1,r,x-tree[p*2]) ;
}
int query5(int p,int l,int r,int x)
{
    if(l==r) return l;
    int mid=(l+r)>>1,res=-1;
    // 错误点:mid<x的判断不严谨,应该是x > mid(等价但更易读),且漏判“左子树有值但右子树没值”的场景
    if(mid<x && tree[p*2+1]>0) res=query5(p*2+1,mid+1,r,x);
    if(res==-1) res=query5(p*2,l,mid,x);
    return res;    
}
int query6(int p,int l,int r,int x) {
    if(l == r) return l;
    int mid = (l + r) >> 1, res=-1;
    // 正确逻辑:先查左子树(仅当左子树有值且mid >= x时,才可能有后继)
    if(tree[p*2+1] > 0 && mid >= x) return query6(p*2+1, mid+1, r, x);
    // 左子树没找到,再查右子树
    else return query6(p*2,l,mid,x);
}

signed main()
{
	unordered_map<int,int> mp;
	vector<int> v;
	int Q[100005][2];
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int opt,x;
		cin>>opt>>x;
		Q[i][0]=opt,Q[i][1]=x;
		v.push_back(x);
	}
	sort(v.begin(),v.end());
	v.erase(unique(v.begin(),v.end()),v.end());
	for(int i=0;i<v.size();i++)
	{
		mp[v[i]]=i+1;
	}
	for(int i=1;i<=n;i++)
	{
		if(Q[i][0]==1)
		{
			update12(1,1,v.size(),mp[Q[i][1]],1);
		}
		else if(Q[i][0]==2)
		{
			update12(1,1,v.size(),mp[Q[i][1]],-1);
		}
		else if(Q[i][0]==3)
		{
			cout<<query3(1,1,v.size(),mp[Q[i][1]])+1<<"\n";
		}
		else if(Q[i][0]==4)
		{
			cout<<v[query4(1,1,v.size(),Q[i][1])-1]<<"\n";
		}
		else if(Q[i][0]==5)
		{
			cout<<v[query5(1,1,v.size(),mp[Q[i][1]])-1]<<"\n";
		}
		else
		{
			cout<<v[query6(1,1,v.size(),mp[Q[i][1]])-1]<<"\n";
		}
	}
	return 0;
}
``

回复

18 条回复,欢迎继续交流。

正在加载回复...