ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

题意:给定一个正整数序列,操作是1.区间赋值,2.区间大于x的数与x取gcd,最后输出操作后的序列

用平衡树维护相同数组成的连续段,每次操作至多增加两个连续段,操作2记录一下区间最小值然后暴力修改,每个数在被修改次数不会超过质因数个数,于是均摊单次修改复杂度在log^2(n)左右

#include<bits/stdc++.h>
char buf[12000000],*ptr=buf-1;
int _(){
    int x=0,c=*++ptr;
    while(c<48)c=*++ptr;
    while(c>47)x=x*10+c-48,c=*++ptr;
    return x;
}
int gcd(int a,int b){
    for(int c;b;c=a,a=b,b=c%b);
    return a;
}
void mins(int&a,int b){if(a<b)a=b;}
int T;
struct node{
    int l,r,x,mx,rnd;
    node*lc,*rc;
    void pr(){
        if(!this)return;
        lc->pr();
        for(int i=l;i<=r;++i)printf("%d ",x);
        rc->pr();
    }
    void up(){
        mx=x;
        if(lc)mins(mx,lc->mx);
        if(rc)mins(mx,rc->mx);
    }
    void gcds(int v){
        if(!this||mx<=v)return;
        if(x>v)x=gcd(x,v);
        lc->gcds(v);
        rc->gcds(v);
        up();
    }
}ns[100055],*ss[100055],*rt;
struct drt{node*lc,*rc;};
int sp=0;
node*_new(int l,int r,int x){
    node*w=ss[--sp];
    w->l=l;w->r=r;w->mx=w->x=x;
    return w;
}
void del(node*&w){
    if(!w)return;
    del(w->lc);
    del(w->rc);
    ss[sp++]=w;
    w=0;
}
node*merge(node*a,node*b){
    if(!a)return b;
    if(!b)return a;
    if(a->rnd>b->rnd){
        a->rc=merge(a->rc,b);
        a->up();
        return a;
    }
    b->lc=merge(a,b->lc);
    b->up();
    return b; 
}
drt split(node*w,int x){
    if(!w)return (drt){0,0};
    drt m;
    if(w->l>=x){
        m=split(w->lc,x);
        w->lc=m.rc;
        m.rc=w;
        w->up();
        return m;
    }
    if(w->r<x){
        m=split(w->rc,x);
        w->rc=m.lc;
        m.lc=w;
        w->up();
        return m;
    }
    node*u=m.lc=_new(w->l,x-1,w->x);
    u->lc=w->lc;
    u->up();
    m.rc=w;
    w->lc=0;w->l=x;
    w->up();
    return m;
}
int main(){
    fread(buf,1,sizeof(buf),stdin);
    srand(29139);
    for(int i=1;i<=100050;++i)(ss[sp++]=ns+i)->rnd=rand();
    for(T=_();T;--T){
        int n=_();
        rt=0;
        for(int i=1;i<=n;++i){
            node*w=_new(i,i,_());
            rt=merge(rt,w);
        }
        for(int q=_(),o,l,r,x;q;--q){
            o=_();l=_();r=_();x=_();
            if(o==1){
                drt a=split(rt,l);
                drt b=split(a.rc,r+1);
                del(b.lc);
                node*w=_new(l,r,x);
                rt=merge(a.lc,merge(w,b.rc));
            }else{
                drt a=split(rt,l);
                drt b=split(a.rc,r+1);
                b.lc->gcds(x);
                rt=merge(a.lc,merge(b.lc,b.rc));
            }
        }
        rt->pr();
        putchar(10);
        del(rt);
    }
    return 0;
}

 

posted on 2017-01-23 15:28  nul  阅读(144)  评论(0编辑  收藏  举报