ABC F求调
  • 板块学术版
  • 楼主kevinZ99
  • 当前回复6
  • 已保存回复6
  • 发布时间2024/3/2 22:26
  • 上次更新2024/3/3 10:04:54
查看原帖
ABC F求调
1117080
kevinZ99楼主2024/3/2 22:26
/*
  Author:Kevin Z K Y
  t_limit:
  m_limit:
*/
//mod 998244353 \ 1e9+7 \ 1e9+9 \ 19260817 \ 104857601
#include <bits/stdc++.h>
#define putendl putchar('\n')
#define rep(f,a) for(auto (f):(a))
#define up(a,b,c) for(int (a)=(b);(a)<=(c);(a)++)
#define dn(a,b,c) for(int (a)=(b);(a)>=(c);(a)--)
using namespace std;
using vi = vector<int> ;
using ll = long long ;
using hint = __int128 ;
using PII = pair<int,int> ;
using PLL = pair<ll,ll> ;
namespace my{
	void IOS(){ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);}
	const int N=(int)2e5+5;
	string outputtemp;
	int max(int x,int y){
		return x>=y?x:y;
	}
	int min(int x,int y){
		return x<=y?x:y;
	}
	#define mid (l+r)/2
	int ls(int p){
		return p*2;
	}
	int rs(int p){
		return p*2+1;
	}
	int n,q;
	int a[N];
	int m1[(N<<3)],m2[(N<<3)];
	int t1[(N<<3)],t2[(N<<3)];
	void push_up(int p){
		int mx1=max(m1[ls(p)],m1[rs(p)]);
		t1[p]=0;
		m1[p]=mx1;
		if(mx1==m1[ls(p)])t1[p]+=t1[ls(p)];
		if(mx1==m1[rs(p)])t1[p]+=t1[rs(p)];
		int mx2=0;
		if(m1[ls(p)]==m1[rs(p)])mx2=max(m2[ls(p)],m2[rs(p)]);
		else mx2=min(m1[ls(p)],m1[rs(p)]);
		m2[p]=mx2;
		if(mx2==0){
			t2[p]=0;
			return ;
		}
		t2[p]=0;
		if(m1[ls(p)]==mx2)t2[p]+=t1[ls(p)];
		if(m1[rs(p)]==mx2)t2[p]+=t1[rs(p)];
		if(m2[ls(p)]==mx2)t2[p]+=t2[ls(p)];
		if(m2[rs(p)]==mx2)t2[p]+=t2[rs(p)];
	}
	void build(int l,int r,int p){
		if(l==r){
			t1[p]=1;
			t2[p]=0;
			m2[p]=0;
			m1[p]=a[l];
			return ;
		}
		build(l,mid,ls(p));build(mid+1,r,rs(p));
		push_up(p);
	}
	void change(int l,int r,int pos,int x,int p){
		if(r<pos||l>pos)return ;
		if(l==pos&&r==pos){
			m1[p]=x;
			t1[p]=1;
			m2[p]=0;
			return ;
		}
		change(l,mid,pos,x,ls(p));change(mid+1,r,pos,x,rs(p));
		push_up(p);
	}
	int findmx1(int l,int r,int L,int R,int p){
		if(r<L||l>R)return 0;
		if(l>=L&&r<=R)return m1[p];
		return max(findmx1(l,mid,L,R,ls(p)),findmx1(mid+1,r,L,R,rs(p)));
	}
	int findmx2(int l,int r,int L,int R,int x,int p){
		if(r<L||l>R)return 0;
		if(l>=L&&r<=R){
			int ret=0;
			if(m1[p]<x)ret=max(m1[p],ret);
			if(m2[p]<x)ret=max(m2[p],ret);
			return ret;
		}
		return max(findmx2(l,mid,L,R,x,ls(p)),findmx2(mid+1,r,L,R,x,rs(p)));
	}
	int ask(int l,int r,int L,int R,int x,int p){
		if(r<L||l>R)return 0;
		if(l>=L&&r<=R){
			if(m1[p]==x)return t1[p];
			if(m2[p]==x)return t2[p];
			return 0;
		}
		return ask(l,mid,L,R,x,ls(p))+ask(mid+1,r,L,R,x,rs(p));
	}
	void input(){
		cin>>n>>q;
		up(i,1,n)cin>>a[i];
		#undef mid
	}
	void output(){
		build(1,n,1);
		while(q--){
			int op,x,y;
			cin>>op>>x>>y;
			if(op==1)change(1,n,x,y,1);
			if(op==2){
				int mx1=findmx1(1,n,x,y,1);
				int mx2=findmx2(1,n,x,y,mx1,1);
				if(mx2==0){
					cout<<0<<'\n';
					continue;
				}
				int ret=ask(1,n,x,y,mx2,1);
				cout<<ret<<'\n';
			}
		}
	}
	void solve(){
		IOS();
		input();
		output();
	}
}
int main(){
//  freopen("","r",stdin);
//  freopen("","w",stdout);
	int _=1;
	while(_--)my::solve();
	return 0;
}

QAQ 以前没有打过类似维护最大值的,赛时自己想的

2024/3/2 22:26
加载中...