30pts求条,玄关
查看原帖
30pts求条,玄关
539345
OrinLoong楼主2024/11/5 15:56
#include <bits/stdc++.h>
using namespace std;
const int MaxN=3e5+5,Inf=0x3f3f3f3f;
int N,M,A[MaxN],C[MaxN],cnt,Opt,X,Y,K,pre[MaxN];
unordered_map<int,set<int> >mp;
set<int>::iterator ite;
int calcgcd(int x,int y){return y?calcgcd(y,x%y):x;}
struct SegTree1{
    int nmx[MaxN<<2],nmn[MaxN<<2],pmx[MaxN<<2];
    void init(){
        memset(nmx,0,sizeof(nmx));
        memset(nmn,0,sizeof(nmn));
        memset(pmx,0,sizeof(pmx));
    }
    int ls(int p){return p<<1;}
    int rs(int p){return (p<<1)|1;}
    void pushup(int p){
        nmx[p]=max(nmx[ls(p)],nmx[rs(p)]);
        nmn[p]=min(nmn[ls(p)],nmn[rs(p)]);
        pmx[p]=max(pmx[ls(p)],pmx[rs(p)]);
    }
    void build(int p,int l,int r){
        if(l==r){nmx[p]=nmn[p]=A[l],pmx[p]=pre[l];return;}
        int mid=(l+r)>>1;build(ls(p),l,mid),build(rs(p),mid+1,r);pushup(p);
    }
    void update(int p,int l,int r,int x){
        if(l==r){nmx[p]=nmn[p]=A[l],pmx[p]=pre[l];return;}int mid=(l+r)>>1;
        (x<=mid)?update(ls(p),l,mid,x):update(rs(p),mid+1,r,x);pushup(p);
    }
    int getnmx(int p,int l,int r,int x,int y){
        if(x<=l&&r<=y)return nmx[p];int mid=(l+r)>>1,res=0;
        if(x<=mid)res=max(res,getnmx(ls(p),l,mid,x,y));
        if(y>mid)res=max(res,getnmx(rs(p),mid+1,r,x,y));
        return res;
    }
    int getnmn(int p,int l,int r,int x,int y){
        if(x<=l&&r<=y)return nmn[p];int mid=(l+r)>>1,res=Inf;
        if(x<=mid)res=min(res,getnmn(ls(p),l,mid,x,y));
        if(y>mid)res=min(res,getnmn(rs(p),mid+1,r,x,y));
        return res;
    }
    int getpmx(int p,int l,int r,int x,int y){
        if(x<=l&&r<=y)return pmx[p];int mid=(l+r)>>1,res=0;
        if(x<=mid)res=max(res,getpmx(ls(p),l,mid,x,y));
        if(y>mid)res=max(res,getpmx(rs(p),mid+1,r,x,y));
        return res;
    }
}SegTr1;
struct SegTree2{
    int gc[MaxN<<2];
    void init(){memset(gc,0,sizeof(gc));}
    int ls(int p){return p<<1;}
    int rs(int p){return (p<<1)|1;}
    void pushup(int p){gc[p]=calcgcd(gc[ls(p)],gc[rs(p)]);}
    void build(int p,int l,int r){
        if(l==r){gc[p]=C[l];return;}int mid=(l+r)>>1;
        build(ls(p),l,mid),build(rs(p),mid+1,r);pushup(p);
    }
    void update(int p,int l,int r,int x){
        if(l==r){gc[p]=C[l];return;}int mid=(l+r)>>1;
        (x<=mid)?update(ls(p),l,mid,x):update(rs(p),mid+1,r,x);pushup(p);
    }
    int getgc(int p,int l,int r,int x,int y){
        if(x<=l&&r<=y)return gc[p];int mid=(l+r)>>1,res=0;
        if(x<=mid)res=calcgcd(res,getgc(ls(p),l,mid,x,y));
        if(y>mid)res=calcgcd(res,getgc(rs(p),mid+1,r,x,y));
        return res;
    }
}SegTr2;
void modify(int x,int y){
    ite=mp[A[x]].find(x);ite++;
    if(ite!=mp[A[x]].end()){pre[*ite]=pre[x];SegTr1.update(1,1,N,*ite);}ite--;
    mp[A[x]].erase(x);A[x]=y;mp[A[x]].insert(x);
    if(mp[A[x]].size()==1){pre[x]=0;}
    else{
        ite=mp[A[x]].find(x);
        if(ite==mp[A[x]].begin())pre[x]=0;
        else{ite--;pre[x]=*ite;ite++;} 
        ite++;if(ite!=mp[A[x]].end()){pre[*ite]=x;SegTr1.update(1,1,N,*ite);}ite--;
    }
    SegTr1.update(1,1,N,x);
    if(x>1){C[x-1]=abs(A[x]-A[x-1]);SegTr2.update(1,1,N-1,x-1);}
    if(x<N){C[x]=abs(A[x+1]-A[x]);SegTr2.update(1,1,N-1,x);}
    //改gcd
}
bool judge(int x,int y,int k){
    if(SegTr1.getnmx(1,1,N,x,y)-SegTr1.getnmn(1,1,N,x,y)!=(y-x)*k){
        // printf("F1");
        return false;}
    if(SegTr2.getgc(1,1,N-1,x,y-1)!=k){
        // printf("F2");
        return false;}
    if(k&&SegTr1.getpmx(1,1,N,x,y)>=x){
        // printf("F3");
        return false;}
    return true;
}
int main(){
    // freopen("smp1.in","r",stdin);
    // freopen("myans.out","w",stdout);
    scanf("%d%d",&N,&M);SegTr1.init();SegTr2.init();
    for(int i = 1;i <= N;i++)scanf("%d",&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]=0;
        else{ite=mp[A[i]].end();--ite;pre[i]=*ite;}
        mp[A[i]].insert(i);
    }
    SegTr1.build(1,1,N);SegTr2.build(1,1,N-1);
    for(int i = 1;i <= M;i++){
        // printf("i=%d\n",i);
        scanf("%d%d%d",&Opt,&X,&Y);
        X^=cnt,Y^=cnt;
        if(Opt==1)modify(X,Y);
        if(Opt==2){
            scanf("%d",&K);K^=cnt;
            if(judge(X,Y,K)){printf("Yes\n");cnt++;}
            else printf("No\n");
        }
    }
    // printf("gmx(3,6)=%d,gmn(3,6)=%d\n",SegTr1.getnmx(1,1,N,3,6),SegTr1.getnmn(1,1,N,3,6));
    return 0;
}
2024/11/5 15:56
加载中...