思路: 可以发现有(<,>)*(P,N)4种情况,分别对应一下四种情况
> | < | |
---|---|---|
Positive | ( − ∞ -\infty −∞,-x),(x, + ∞ +\infty +∞)强制转负 | ( − ∞ -\infty −∞,-x],[x, + ∞ +\infty +∞)强制转正 (-x,x)反转 |
Negative | ( − ∞ -\infty −∞,-x],[x, + ∞ +\infty +∞)强制转负 (-x,x)反转 | ( − ∞ -\infty −∞,-x),(x, + ∞ +\infty +∞)强制转正 |
维护线段树a位为反转位,b位为强制位
强制位之下的线段不存在用处
#include
using namespace std;
const int MAX_N = 1e5 + 5;
struct nd {
int a, b;
nd(int a = 1, int b = 0) :a(a), b(b) {}
}dat[MAX_N*4];
int a[MAX_N];
int n, q;
void PD(int k) {
int& aa = dat[k].a;
if (dat[k].b) {
dat[2 * k + 1].a = dat[2 * k + 2].a = 1;
dat[2 * k + 1].b = dat[2 * k + 2].b = dat[k].b;
}
dat[2 * k + 1].a *= aa;
dat[2 * k + 2].a *= aa;
aa = 1;
dat[k].b = 0;
}
void harsh(int a, int b, int l, int r, int k, int x) {
if (a <= l && r <= b) {
dat[k].a = 1; dat[k].b = x;
}
else if (r <= a || b <= l) return;
else {
PD(k);
harsh(a, b, l, (l + r) >> 1, 2 * k + 1, x);
harsh(a, b, (l + r) >> 1, r, 2 * k + 2, x);
}
}
void change(int a, int b, int l, int r, int k) {
if (a <= l && r <= b) {
dat[k].a *= -1;
}
else if (r <= a || b <= l) return;
else {
PD(k);
change(a, b, l, (l + r) >> 1, 2 * k + 1);
change(a, b, (l + r) >> 1, r, 2 * k + 2);
}
}
int ask(int a, int l, int r, int k, int s) {
if (dat[k].b)
{
return dat[k].b*dat[k].a*abs(s);
}
if (r - l == 1) return dat[k].a*s;
int m = (l + r) >> 1;
if (a < m) return dat[k].a*ask(a, l, m, 2 * k + 1,s);
else return dat[k].a*ask(a, m, r, 2 * k + 2,s);
}
int main() {
ios::sync_with_stdio(false);
cin >> n >> q;
for (int i = 0; i < n; i++) cin >> a[i];
int N = 1e5+2;
string s;
for (int i = 0, x; i < q; i++) {
cin >> s >> x;
bool larger = s[0] == '>'?true : false;
bool symbol = x >= 0 ? true : false;
x = abs(x); int t = larger ? -1 : 1;
if (larger && symbol) {
harsh(x + 1, N, 0, N, 0, t);
}
else if (larger && !symbol) {
harsh(x , N, 0, N, 0, t);
change(1, x , 0, N, 0);
}
else if (!larger && symbol) {
harsh(x, N, 0, N, 0, t);
change(1, x, 0, N, 0);
}
else {
harsh(x + 1, N, 0, N, 0, t);
}
}
for (int i = 0; i < n; i++) {
cout << ask(abs(a[i]), 0, N, 0, a[i]) << " ";
}
cout << endl;
//system("pause");
}