Description
Input
Output
Sample Input
Sample Output
题意:1操作代表改区间为x,2操作代表对于区间如果这个数>x的话就改成两个数的gcd
思路:线段树区间修改,队友给的思路,多一个flag代表的是这个区间的数是否都是一样的
#include
#include
#include
#include
#include
#define lson(x) ((x) << 1)
#define rson(x) ((x) << 1 | 1)
typedef long long ll;
using namespace std;
const int MAXN = 100005;
const int ROOT = 1;
int gcd(int a,int b) {
return b?gcd(b,a%b):a;
}
struct seg {
int w;
int v;
int flag;
};
struct segment_tree {
seg node[MAXN << 2];
void update(int pos) {
node[pos].flag = (node[lson(pos)].flag && node[rson(pos)].flag && node[lson(pos)].w == node[rson(pos)].w);
node[pos].w = node[lson(pos)].w;
}
void build(int l, int r, int pos) {
node[pos].flag = 0;
node[pos].v = -1;
if (l == r) {
scanf("%d", &node[pos].w);
node[pos].flag = 1;
return;
}
int m = l + r >> 1;
build(l, m, lson(pos));
build(m + 1, r, rson(pos));
update(pos);
}
void push(int l, int r, int pos) {
if (node[pos].v != -1) {
node[lson(pos)].v = node[rson(pos)].v = node[pos].v;
node[lson(pos)].w = node[rson(pos)].w = node[pos].v;
node[pos].v = -1;;
}
}
void modify(int l, int r, int pos, int x, int y, int z) {
if (x <= l && r <= y) {
node[pos].w = z;
node[pos].v = z;;
/* node[pos].flag = z; is wrong. */
return;
}
push(l, r, pos);
int m = l + r >> 1;
if (x <= m) modify(l, m, lson(pos), x, y, z);
if (y > m) modify(m + 1, r, rson(pos), x, y, z);
update(pos);
}
void modify1(int l, int r, int pos, int x, int y, int z) {
if (node[pos].flag && node[pos].w <= z)
return;
if (x <= l && y >= r && node[pos].flag) {
node[pos].w = gcd(node[pos].w, z);
node[pos].v = node[pos].w;
return;
}
push(l, r, pos);
int m = l + r >> 1;
if (x <= m) modify1(l, m, lson(pos), x, y, z);
if (y > m) modify1(m + 1, r, rson(pos), x, y, z);
update(pos);
}
int query(int l, int r, int pos, int x, int y) {
if (x <= l && r <= y) return node[pos].w;
push(l, r, pos);
int m = l + r >> 1;
int res = 0;
if (x <= m) res += query(l, m, lson(pos), x, y);
if (y > m) res += query(m + 1, r, rson(pos), x, y);
return res;
}
} tree;
int main() {
int t, n, m;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
tree.build(1, n, 1);
scanf("%d", &m);
int op, l, r, x;
while (m--) {
scanf("%d%d%d%d", &op, &l, &r, &x);
if (op == 1)
tree.modify(1, n, 1, l, r, x);
else tree.modify1(1, n, 1, l, r, x);
}
for (int i = 1; i <= n; i++)
printf("%d ", tree.query(1, n, 1, i, i));
printf("\n");
}
return 0;
}