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;
}

  

 

posted @ 2015-01-12 19:15  Claris  阅读(202)  评论(0编辑  收藏  举报