线段树维护区间次小值求条(玄一关)
查看原帖
线段树维护区间次小值求条(玄一关)
760171
Binah_cyc楼主2024/3/21 21:13

rt

#include<bits/stdc++.h>
using namespace std;
//#define int long long
#define x first
#define y second
#define mkp make_pair
int n,q,a[200005];
struct SegmentTree
{
	int l,r;
	int maxn,scmaxn;
	int maxncnt,scmaxncnt;
} t[200005<<2];
bool cmp(pair<int,int> a,pair<int,int> b)
{
	return a.x>b.x;
}
set<int> s;
void pushup(int p)
{
	s.clear();
	t[p].maxncnt=t[p].scmaxncnt=0;
	t[p].maxn=max(t[p*2].maxn,t[p*2+1].maxn);
	if(t[p].maxn==t[p*2].maxn) t[p].maxncnt+=t[p*2].maxncnt;
	if(t[p].maxn==t[p*2+1].maxn) t[p].maxncnt+=t[p*2+1].maxncnt;
	s.insert(t[p*2].maxn);
	s.insert(t[p*2+1].maxn);
	if(t[p*2].scmaxn) s.insert(t[p*2].scmaxn);
	if(t[p*2+1].scmaxn) s.insert(t[p*2+1].scmaxn);
	if(s.size()==1) return ;
	auto it=s.end();
	it--,it--;
	t[p].scmaxn=*it;
	if(t[p].scmaxn==t[p*2].maxn) t[p].scmaxncnt+=t[p*2].maxncnt;
	if(t[p].scmaxn==t[p*2+1].maxn) t[p].scmaxncnt+=t[p*2+1].maxncnt;	
	if(t[p].scmaxn==t[p*2].scmaxn) t[p].scmaxncnt+=t[p*2].scmaxncnt;
	if(t[p].scmaxn==t[p*2+1].scmaxn) t[p].scmaxncnt+=t[p*2+1].scmaxncnt;
	return ;
}
SegmentTree merge(SegmentTree a,SegmentTree b)
{
	SegmentTree ans;
	s.clear();
	ans.maxncnt=ans.scmaxncnt=0;
	ans.maxn=max(a.maxn,b.maxn);
	if(ans.maxn==a.maxn) ans.maxncnt+=a.maxncnt;
	if(ans.maxn==b.maxn) ans.maxncnt+=b.maxncnt;
	s.insert(a.maxn);
	s.insert(b.maxn);
	if(a.scmaxn) s.insert(a.scmaxn);
	if(b.scmaxn) s.insert(b.scmaxn);
	if(s.size()==1)
	{
		ans.scmaxn=0;
		return ans;
	}
	auto it=s.end();
	it--,it--;
	ans.scmaxn=*it;
	if(ans.scmaxn==a.maxn) ans.scmaxncnt+=a.maxncnt;
	if(ans.scmaxn==b.maxn) ans.scmaxncnt+=b.maxncnt;	
	if(ans.scmaxn==a.scmaxn) ans.scmaxncnt+=a.scmaxncnt;
	if(ans.scmaxn==b.scmaxn) ans.scmaxncnt+=b.scmaxncnt;
	return ans;
}
void build(int l,int r,int p)
{
	t[p].l=l,t[p].r=r;
	if(l==r) return (void)(t[p].maxn=a[l],t[p].maxncnt=1);
	int mid=(l+r)>>1;
	build(l,mid,p*2),build(mid+1,r,p*2+1);
	pushup(p);
}
void change(int l,int r,int p,int k)
{
	if(l<=t[p].l&&t[p].r<=r) return (void)(t[p].maxn=k);
	int mid=(t[p].l+t[p].r)>>1;
	if(l<=mid) change(l,r,p*2,k);
	if(r>mid)  change(l,r,p*2+1,k);
	pushup(p);
}
SegmentTree ask(int l,int r,int p)
{
	if(l<=t[p].l&&t[p].r<=r) return t[p];
	int mid=(t[p].l+t[p].r)>>1;
	if(l<=mid&&r>mid) return merge(ask(l,r,p*2),ask(l,r,p*2+1));
	else if(l<=mid) return ask(l,r,p*2);
	else return ask(l,r,p*2+1);
}
signed main()
{
//	freopen("1.out","w",stdout);
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin>>n>>q;
	for(int i=1; i<=n; i++) cin>>a[i];
	build(1,n,1);
	while(q--)
	{
		int op,l,r;
		cin>>op>>l>>r;
		if(op==1) change(l,l,1,r);
		else if(op==2) cout<<ask(l,r,1).scmaxncnt<<'\n';
	}
	return 0;
}

第三个样例没过,但是数据全过了

2024/3/21 21:13
加载中...