//906MS 1972K
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define lch(x) ((x)<<1)
#define rch(x) ((x)<<1 | 1)
using namespace std;
const int maxn = 100000;
int num[maxn+5];
int tree[maxn<<2];
bool flag[maxn<<2];
int gcd(int x, int y){
return y == 0 ? x : gcd(y, x%y);
}
void build(int n, int l, int r){
flag[n] = false; //所有节点标记置0
if(l == r){
tree[n] = num[l];
return;
}
int mid = (l + r) >> 1;
build(lch(n), l, mid);
build(rch(n), mid+1, r);
}
inline void push_up(int n){
if(tree[lch(n)] == tree[rch(n)]){
tree[n] = tree[lch(n)];
flag[n] = true;
}
}
inline void push_down(int n){
if(flag[n]){ //有标记才下传
flag[lch(n)] = flag[rch(n)] = true;
tree[lch(n)] = tree[rch(n)] = tree[n];
flag[n] = false;
}
}
void seg_set(int a, int b, int v, int n, int l, int r){
if(a <= l && r <= b){
tree[n] = v;
flag[n] = true;
return;
}
push_down(n); //区间[l, r]没有完全被[a, b]覆盖,则需要尝试标记下传
int mid = (l + r) >> 1;
if(b <= mid) seg_set(a, b, v, lch(n), l, mid); //抛弃右段
else if(mid+1 <= a) seg_set(a, b, v, rch(n), mid+1, r); //抛弃左段
else {
seg_set(a, b, v, lch(n), l, mid);
seg_set(a, b, v, rch(n), mid+1, r);
}
if(flag[lch(n)] && flag[rch(n)]) push_up(n);
}
void modify(int a, int b, int x, int n, int l, int r){
if(flag[n] && a <= l && r <= b){ //边界1:到了标记节点且该节点对应的区间被完全覆盖
if(tree[n] > x) tree[n] = gcd(tree[n], x);
return;
}
if(l == r){ //边界2:到了叶子节点
if(tree[n] > x) tree[n] = gcd(tree[n], x);
return;
}
push_down(n);
int mid = (l + r) >> 1;
if(b <= mid) modify(a, b, x, lch(n), l, mid); //抛弃右段
else if(mid+1 <= a) modify(a, b, x, rch(n), mid+1, r); //抛弃左段
else {
modify(a, b, x, lch(n), l, mid);
modify(a, b, x, rch(n), mid+1, r);
}
if(flag[lch(n)] && flag[rch(n)]) push_up(n);
}
void print(int a, int b, int n, int l, int r){
if(flag[n]){ //边界1:到了标记节点
for(int i=l; i<=r; i++) printf("%d ", tree[n]);
return;
}
if(l == r){ //边界2:到了叶子节点
printf("%d ", tree[n]);
return;
}
int mid = (l+r)>>1;
print(a, b, lch(n), l, mid);
print(a, b, rch(n), mid+1, r);
}
int main(){
int T; scanf("%d", &T);
while(T--){
int n, Q;
scanf("%d", &n);
for(int i=1; i<=n; i++)
scanf("%d", &num[i]);
build(1, 1, n);
scanf("%d", &Q);
while(Q--){
int t, l, r, x;
scanf("%d%d%d%d", &t, &l, &r, &x);
if(t == 1) seg_set(l, r, x, 1, 1, n);
else modify(l, r, x, 1, 1, n);
}
print(1, n, 1, 1, n);
printf("\n");
}
return 0;
}
hdu 4902 Nice boat(第二篇) 带push_up操作
最新推荐文章于 2021-10-08 22:54:51 发布