题意:1操作让区间l~r的值为x 2操作让区间大于x的值为gcd(x,ai)
我们维护区间最大值最小值 当最大值等于最小值时 区间的数都相同 这样可以减少2操作的时间 另外 对于mx[id]<=x的区间我们不必要在更新 也可以剪掉
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e5+10;
int a[N],ans[N];
int mx[N<<2],mi[N<<2],lazy[N<<2];
#define ls (id<<1)
#define rs (ls|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
void pushup(int id){
mx[id]=max(mx[ls],mx[rs]);
mi[id]=min(mi[ls],mi[rs]);
}
void cal(int id,int val){
mx[id]=mi[id]=val;
lazy[id]=1;
}
void pushdown(int id){
if(lazy[id]){
cal(ls,mx[id]);
cal(rs,mx[id]);
lazy[id]=0;
}
}
void build(int id,int l,int r){
lazy[id]=0;
if(l==r){
mx[id]=mi[id]=a[l];
return;
}
int mid = l+r>>1;
build(lson);build(rson);
pushup(id);
}
void update(int id,int l,int r,int L,int R,int op,int val){
if(op==2&&mx[id]<=val) return;
if(L<=l&&R>=r){
if(op==1){
cal(id,val);
return;
}else{
if(mx[id]==mi[id]){
cal(id,__gcd(mx[id],val));
return;
}
}
}
pushdown(id);
int mid = l+r>>1;
if(L<=mid) update(lson,L,R,op,val);
if(R>mid) update(rson,L,R,op,val);
pushup(id);
}
void query(int id,int l,int r){
if(l==r){
ans[l]=mx[id];
return;
}
pushdown(id);
int mid = l+r>>1;
query(lson);query(rson);
}
int main(){
int f;
scanf("%d",&f);
while(f--){
int n;
scanf("%d",&n);
for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
build(1,1,n);
int m;
scanf("%d",&m);
for(int i = 1; i <= m; i++){
int op,l,r,x;
scanf("%d%d%d%d",&op,&l,&r,&x);
update(1,1,n,l,r,op,x);
}
query(1,1,n);
for(int i = 1; i <= n; i++) printf("%d ",ans[i]);
puts("");
}
return 0;
}