P5278 算术天才⑨与等差数列求调
  • 板块灌水区
  • 楼主zhx20081129
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/8/29 15:08
  • 上次更新2024/8/29 17:33:49
查看原帖
P5278 算术天才⑨与等差数列求调
914572
zhx20081129楼主2024/8/29 15:08
#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int N=6e5+7,INF=1e18;
#define ls (u<<1)
#define rs (u<<1|1)
#define mid (l+r>>1)
int n,m,a[N],k,cnt,pre[N],c[N];
unordered_map<int,set<int> >mp;
set<int>::iterator it; 
struct T{
	int mx[N<<2],mn[N<<2],p[N<<2];
	void up(int u){
		mn[u]=min(mn[ls],mn[rs]);
		mx[u]=max(mx[ls],mx[rs]);
		p[u]=max(p[ls],p[rs]);
	}
	void build(int u,int l,int r){
		if(l==r){
			mn[u]=mx[u]=a[l],p[u]=pre[l];
			return;
		}
		build(ls,l,mid);
		build(rs,mid+1,r);
		up(u);
	}
	void change(int u,int l,int r,int pos,int k){
		if(l==r&&l==pos){
			mn[u]=mx[u]=k,p[u]=pre[l];
			return;
		}
		if(mid>=pos)change(ls,l,mid,pos,k);
		else change(rs,mid+1,r,pos,k);
		up(u);
	}
	int findmx(int u,int l,int r,int ql,int qr){
		if(ql<=l&&r<=qr)return mx[u];
		int res=-INF;
		if(ql<=mid)res=max(res,findmx(ls,l,mid,ql,qr));
		if(mid<qr)res=max(res,findmx(rs,mid+1,r,ql,qr));
		return res;
	}
	int findmn(int u,int l,int r,int ql,int qr){
		if(ql<=l&&r<=qr)return mn[u];
		int res=INF;
		if(ql<=mid)res=min(res,findmn(ls,l,mid,ql,qr));
		if(mid<qr)res=min(res,findmn(rs,mid+1,r,ql,qr));
		return res;
	} 
	int findp(int u,int l,int r,int ql,int qr){
		if(ql<=l&&r<=qr)return p[u];
		int res=-INF;
		if(ql<=mid)res=max(res,findp(ls,l,mid,ql,qr));
		if(mid<qr)res=max(res,findp(rs,mid+1,r,ql,qr));
		return res; 
	}
}t;
struct D{
	int d[N<<2];
	void up(int u){
		d[u]=__gcd(d[ls],d[rs]);
	}
	void build(int u,int l,int r){
		if(l==r){
			d[u]=c[l];
			return;
		}
		build(ls,l,mid);build(rs,mid+1,r);
		up(u); 
	}
	void change(int u,int l,int r,int pos){
		if(l==r&&l==pos){
			d[u]=c[pos];
			return;
		}
		if(mid>=pos)change(ls,l,mid,pos);
		else change(rs,mid+1,r,pos);
		up(u);
	}
	int find(int u,int l,int r,int ql,int qr){
		if(ql<=l&&r<=qr){
			return d[u];
		}
		int res=0;
		if(ql<=mid)res=find(ls,l,mid,ql,qr);
		if(qr>mid)res=__gcd(res,find(rs,mid+1,r,ql,qr));
		return res;
	}
}d;
int work(int l,int r,int k){
	if(l==r)return 1;
	int mx=t.findmx(1,1,n,l,r),mn=t.findmn(1,1,n,l,r),gcd=d.find(1,1,n-1,l,r-1),p=t.findp(1,1,n,l,r);
	if(mx-mn!=(r-l)*k)return 0;
	if(k&&p>=l)return 0;
	if(gcd!=k)return 0;
	return 1;
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<n;i++)c[i]=abs(a[i+1]-a[i]);
	for(int i=1;i<=n;i++){
		if(!mp[a[i]].size())pre[i]=-1;
		else{
			it=mp[a[i]].end();it--;
			pre[i]=*it;
		}
		mp[a[i]].insert(i);
	}
	t.build(1,1,n);d.build(1,1,n-1);
	for(int i=1;i<=m;i++){
		int op,x,y;
		cin>>op>>x>>y;
		x^=cnt,y^=cnt;
		if(op==1){
			it=mp[a[x]].find(x);
			if(it!=mp[a[x]].end())++it,pre[*it]=pre[x],t.change(1,1,n,*it,a[*it]);
			mp[a[x]].erase(x),a[x]=y;
			it=mp[a[x]].lower_bound(x);
			if(it!=mp[a[x]].end())pre[*it]=x,t.change(1,1,n,*it,a[*it]);
			if(it==mp[a[x]].begin())pre[x]=-1;
			else --it,pre[x]=*it,mp[a[x]].insert(x);
			c[x]=abs(a[x+1]-a[x]),c[x-1]=abs(a[x]-a[x-1]);
			t.change(1,1,n,x,y);d.change(1,1,n-1,x);
			if(x-1)d.change(1,1,n-1,x-1); 
		} 
		if(op==2){
			cin>>k;k^=cnt;
			if(work(x,y,k)){cout<<"Yes\n";++cnt;}
			else cout<<"No\n";
		}
	}
	return 0;
} 
2024/8/29 15:08
加载中...