第一个想法是标记maxv[o]表示区间最大值,如果maxv[o]>x,那么就不用更新这个区间
另外还用setv[o]作为区间更新值的一个标记
想法很简单,写起来很花时间,平时写的少,写的也特么丑
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;
#define INF 1e9
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define mset(x) memset(x,0,sizeof(x))
typedef __int64 ll;
const int maxn = 100010;
const int maxnode = 100010 * 4;
ll gcd(ll a, ll b){
if(b==0) return a;
return gcd(b, a%b);
}
int a[maxn], n, q, t;
int x1, x2, val, res[maxn];
struct IntervalTree{
int setv[maxnode];
int maxv[maxnode];
void init(){
memset(setv, -1, sizeof(setv));
mset(maxv);
}
void pushdown(int o){
int lc = 2*o, rc = 2*o+1;
if(setv[o]>=0){
setv[lc] = setv[rc] = setv[o];
maxv[lc] = maxv[rc] = maxv[o];
setv[o] = -1;
}
}
void pushup(int o){
int lc = 2*o, rc = 2*o+1;
maxv[o] = max(maxv[lc], maxv[rc]);
if(setv[lc]==setv[rc]) setv[o] = setv[lc];
else setv[o] = -1;
}
void build(int o, int l, int r){
if(l==r){
setv[o] = a[l];
maxv[o] = a[l];
return;
}
int mid = l+(r-l)/2;
build(2*o, l, mid);
build(2*o+1, mid+1, r);
pushup(o);
}
void setval(int o, int l, int r){
if(x1<=l && x2>=r){
setv[o] = val;
maxv[o] = val;
return ;
}
pushdown(o);
int mid = l+(r-l)/2, lc = 2*o, rc = 2*o+1;
if(x1<=mid) setval(lc, l, mid);
if(x2>mid) setval(rc, mid+1, r);
pushup(o);
}
void turngcd(int o, int l, int r){
if(maxv[o] <= val) return ;
int mid = l+(r-l)/2, lc = 2*o, rc = 2*o+1;
if(x1<=l && x2>=r){
if(setv[o]>=0){
setv[o] = gcd(setv[o], val);
maxv[o] = setv[o];
return ;
}
pushdown(o);
setv[o] = maxv[o] = gcd(setv[o], val);
turngcd(lc, l, mid);
turngcd(rc, mid+1, r);
pushup(o);
return ;
}
pushdown(o);
if(x1<=mid) turngcd(lc, l, mid);
if(x2>mid) turngcd(rc, mid+1, r);
pushup(o);
}
void query(int o, int l, int r){
if(l==r){
res[l] = maxv[o];
return ;
}
pushdown(o);
int mid = l+(r-l)/2;
query(2*o, l, mid);
query(2*o+1, mid+1, r);
}
}tree;
int main(){
// freopen("a.txt","r",stdin);
// freopen(".out","w",stdout);
int kase;
cin>>kase;
while(cin>>n){
tree.init();
rep(i,1,n) scanf("%d", &a[i]);
tree.build(1,1,n);
cin>>q;
while(q--){
scanf("%d%d%d%d", &t, &x1, &x2, &val);
if(t==1) tree.setval(1,1,n);
if(t==2) tree.turngcd(1,1,n);
}
tree.query(1,1,n);
rep(i,1,n) printf("%d ", res[i]);
puts("");
}
return 0;
}
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;
#define INF 1e9
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define mset(x) memset(x,0,sizeof(x))
typedef __int64 ll;
const int maxn = 100010;
const int maxnode = 100010 * 4;
ll gcd(ll a, ll b){
if(b==0) return a;
return gcd(b, a%b);
}
int a[maxn], n, q, t;
int x1, x2, val, res[maxn];
struct IntervalTree{
int setv[maxnode];
void init(){
memset(setv, -1, sizeof(setv));
}
void pushdown(int o){
int lc = 2*o, rc = 2*o+1;
if(setv[o]>=0){
setv[lc] = setv[rc] = setv[o];
setv[o] = -1;
}
}
void pushup(int o){
int lc = 2*o, rc = 2*o+1;
if(setv[lc]==setv[rc]) setv[o] = setv[lc];
else setv[o] = -1;
}
void build(int o, int l, int r){
if(l==r){
setv[o] = a[l];
return;
}
int mid = l+(r-l)/2;
build(2*o, l, mid);
build(2*o+1, mid+1, r);
pushup(o);
}
void setval(int o, int l, int r){
if(x1<=l && x2>=r){
setv[o] = val;
return ;
}
pushdown(o);
int mid = l+(r-l)/2, lc = 2*o, rc = 2*o+1;
if(x1<=mid) setval(lc, l, mid);
if(x2>mid) setval(rc, mid+1, r);
pushup(o);
}
void turngcd(int o, int l, int r){
int mid = l+(r-l)/2, lc = 2*o, rc = 2*o+1;
if(x1<=l && x2>=r && setv[o]>=0){
if(setv[o]>val){
setv[o] = gcd(setv[o], val);
}
return ;
}
pushdown(o);
if(x1<=mid) turngcd(lc, l, mid);
if(x2>mid) turngcd(rc, mid+1, r);
pushup(o);
}
void query(int o, int l, int r){
if(l==r){
res[l] = setv[o];
return ;
}
pushdown(o);
int mid = l+(r-l)/2;
query(2*o, l, mid);
query(2*o+1, mid+1, r);
}
}tree;
int main(){
// freopen("a.txt","r",stdin);
// freopen(".out","w",stdout);
int kase;
cin>>kase;
while(cin>>n){
tree.init();
rep(i,1,n) scanf("%d", &a[i]);
tree.build(1,1,n);
cin>>q;
while(q--){
scanf("%d%d%d%d", &t, &x1, &x2, &val);
if(t==1) tree.setval(1,1,n);
if(t==2) tree.turngcd(1,1,n);
}
tree.query(1,1,n);
rep(i,1,n) printf("%d ", res[i]);
puts("");
}
return 0;
}