zoukankan      html  css  js  c++  java
  • BZOJ3867 : Nice boat

    每个点最多被修改$O(log n)$次,线段树记录区间最值暴力更新。

    #include<cstdio>
    #define N 262145
    int T,n,m,i,op,c,d,p,s[N],v[N],tag[N];
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    int gcd(int a,int b){return b?gcd(b,a%b):a;}
    inline void up(int x){v[x]=v[x<<1]>v[x<<1|1]?v[x<<1]:v[x<<1|1];tag[x]=tag[x<<1]==tag[x<<1|1]?tag[x<<1]:-1;}
    inline void pb(int x){if(~tag[x])tag[x<<1]=tag[x<<1|1]=v[x<<1]=v[x<<1|1]=tag[x];}
    void build(int x,int a,int b){
      if(a==b){tag[x]=v[x]=s[a];return;}
      int mid=(a+b)>>1;
      build(x<<1,a,mid),build(x<<1|1,mid+1,b),up(x);
    }
    void change1(int x,int a,int b){
      if(c<=a&&b<=d){tag[x]=v[x]=p;return;}
      pb(x);
      int mid=(a+b)>>1;
      if(c<=mid)change1(x<<1,a,mid);
      if(d>mid)change1(x<<1|1,mid+1,b);
      up(x);
    }
    void change2(int x,int a,int b){
      if(v[x]<=p)return;
      int mid=(a+b)>>1;
      if(c<=a&&b<=d){
        if(~tag[x])v[x]=tag[x]=gcd(tag[x],p);
        else pb(x),change2(x<<1,a,mid),change2(x<<1|1,mid+1,b),up(x);
        return;
      }
      pb(x);
      if(c<=mid)change2(x<<1,a,mid);
      if(d>mid)change2(x<<1|1,mid+1,b);
      up(x);
    }
    void dfs(int x,int a,int b){
      if(~tag[x]){for(;a<=b;a++)printf("%d ",tag[x]);return;}
      int mid=(a+b)>>1;
      dfs(x<<1,a,mid),dfs(x<<1|1,mid+1,b);
    }
    int main(){
      read(T);
      while(T--){
        read(n);
        for(i=1;i<=n;i++)read(s[i]);
        build(1,1,n);
        read(m);
        while(m--)read(op),read(c),read(d),read(p),op==1?change1(1,1,n):change2(1,1,n);
        dfs(1,1,n);
        puts("");
      }
      return 0;
    }
    

      

  • 相关阅读:
    oracle DBA 常用表和视图
    oracle 索引聚簇表的工作原理
    二进制手表
    二分查找
    二分查找
    排列硬币
    将每个元素替换为右侧最大元素
    搜索插入位置----二分查找
    合并两个有序数组
    在Nuxt遇到的坑
  • 原文地址:https://www.cnblogs.com/clrs97/p/4403159.html
Copyright © 2011-2022 走看看