Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC target ("avx2")
- #pragma GCC optimization ("O3")
- #pragma GCC optimization ("unroll-loops")
- #include <iostream>
- #include <queue>
- #include <vector>
- #include <algorithm>
- #include <cmath>
- #include <string>
- #include <random>
- #define rand() abs((long long)(rnd()))
- using namespace std;
- mt19937 rnd(1337);
- const int N = 524288 * 2; // 2^20, ne zabud vernut *2
- const long long M = 1e9 + 7;
- int n, q;
- long long a[N], b[N], st[61], ODIN;
- struct Node {
- int sum[61];
- int dlt[61];
- int len;
- };
- struct SegTree {
- Node tree[N];
- void init() {
- for (int i = N - 1; i >= 1; i--) {
- if (i >= N / 2) {
- long long x = a[i - N / 2];
- for (int j = 60; j >= 0; j--) {
- tree[i].sum[j] = x / st[j];
- tree[i].dlt[j] = -1;
- x = x % st[j];
- }
- tree[i].len = 1;
- }
- else {
- for (int j = 60; j >= 0; j--) {
- tree[i].sum[j] = tree[i * 2].sum[j] + tree[i * 2 + 1].sum[j];
- tree[i].dlt[j] = -1;
- }
- tree[i].len = tree[i * 2].len * 2;
- }
- }
- }
- void push(int v) {
- if (v >= N / 2) {
- return;
- }
- for (int j = 0; j < 61; j++) {
- if (tree[v].dlt[j] == -1) {
- continue;
- }
- if (tree[v].dlt[j] == 0) {
- tree[v * 2].sum[j] = 0;
- tree[v * 2 + 1].sum[j] = 0;
- tree[v * 2].dlt[j] = 0;
- tree[v * 2 + 1].dlt[j] = 0;
- }
- if (tree[v].dlt[j] == 1) {
- tree[v * 2].sum[j] = tree[v * 2].len;
- tree[v * 2 + 1].sum[j] = tree[v * 2 + 1].len;
- tree[v * 2].dlt[j] = 1;
- tree[v * 2 + 1].dlt[j] = 1;
- }
- if (tree[v].dlt[j] == 2) {
- tree[v * 2].sum[j] = tree[v * 2].len - tree[v * 2].sum[j];
- tree[v * 2 + 1].sum[j] = tree[v * 2 + 1].len - tree[v * 2 + 1].sum[j];
- tree[v * 2].dlt[j] = 2;
- tree[v * 2 + 1].dlt[j] = 2;
- }
- tree[v].dlt[j] = -1;
- }
- }
- void update(int v) {
- v /= 2;
- while (v > 0) {
- for (int j = 0; j < 61; j++) {
- tree[v].sum[j] = tree[v * 2].sum[j] + tree[v * 2 + 1].sum[j];
- }
- v /= 2;
- }
- }
- void And(int v, int l, int r, int L, int R, long long x) {
- if (R < l || L > r) {
- return;
- }
- push(v);
- if (l >= L && r <= R) {
- for (int j = 60; j >= 0; j--) {
- if (x >= st[j]) {
- x -= st[j];
- }
- else {
- tree[v].sum[j] = 0;
- tree[v].dlt[j] = 0;
- }
- }
- update(v);
- return;
- }
- And(v * 2, l, (l + r) / 2, L, R, x);
- And(v * 2 + 1, (l + r) / 2 + 1, r, L, R, x);
- }
- void Or(int v, int l, int r, int L, int R, long long x) {
- if (R < l || L > r) {
- return;
- }
- push(v);
- if (l >= L && r <= R) {
- for (int j = 60; j >= 0; j--) {
- if (x >= st[j]) {
- x -= st[j];
- tree[v].sum[j] = tree[v].len;
- tree[v].dlt[j] = 1;
- }
- else {
- }
- }
- update(v);
- return;
- }
- Or(v * 2, l, (l + r) / 2, L, R, x);
- Or(v * 2 + 1, (l + r) / 2 + 1, r, L, R, x);
- }
- void Xor(int v, int l, int r, int L, int R, long long x) {
- if (R < l || L > r) {
- return;
- }
- push(v);
- if (l >= L && r <= R) {
- for (int j = 60; j >= 0; j--) {
- if (x >= st[j]) {
- x -= st[j];
- tree[v].sum[j] = tree[v].len - tree[v].sum[j];
- tree[v].dlt[j] = 2;
- }
- else {
- }
- }
- update(v);
- return;
- }
- Xor(v * 2, l, (l + r) / 2, L, R, x);
- Xor(v * 2 + 1, (l + r) / 2 + 1, r, L, R, x);
- }
- void xors(int l, int r, long long x) {
- Xor(1, 1, N / 2, l, r, x);
- }
- void ors(int l, int r, long long x) {
- Or(1, 1, N / 2, l, r, x);
- }
- void ands(int l, int r, long long x) {
- And(1, 1, N / 2, l, r, x);
- }
- long long get_and(int v, int l, int r, int L, int R) {
- if (R < l || L > r) {
- return ODIN;
- }
- push(v);
- if (l >= L && r <= R) {
- long long x = 0;
- for (int j = 60; j >= 0; j--) {
- if (tree[v].sum[j] == tree[v].len) {
- x += st[j];
- }
- }
- return x;
- }
- return get_and(v * 2, l, (l + r) / 2, L, R) &
- get_and(v * 2 + 1, (l + r) / 2 + 1, r, L, R);
- }
- long long get_or(int v, int l, int r, int L, int R) {
- if (R < l || L > r) {
- return 0;
- }
- push(v);
- if (L <= l && R >= r) {
- long long x = 0;
- for (int j = 60; j >= 0; j--) {
- if (tree[v].sum[j]) {
- x += st[j];
- }
- }
- return x;
- }
- return get_or(v * 2, l, (l + r) / 2, L, R) |
- get_or(v * 2 + 1, (l + r) / 2 + 1, r, L, R);
- }
- long long get_xor(int v, int l, int r, int L, int R) {
- if (R < l || L > r) {
- return 0;
- }
- push(v);
- if (l >= L && r <= R) {
- long long x = 0;
- for (int j = 60; j >= 0; j--) {
- if (tree[v].sum[j] & 1) {
- x += st[j];
- }
- }
- return x;
- }
- return get_xor(v * 2, l, (l + r) / 2, L, R) ^
- get_xor(v * 2 + 1, (l + r) / 2 + 1, r, L, R);
- }
- long long get_x(int l, int r) {
- return get_xor(1, 1, N / 2, l, r);
- }
- long long get_o(int l, int r) {
- return get_or(1, 1, N / 2, l, r);
- }
- long long get_a(int l, int r) {
- return get_and(1, 1, N / 2, l, r);
- }
- };
- SegTree t;
- string type, op;
- int l, r;
- long long x;
- int main()
- {
- st[0] = 1;
- ODIN = 1;
- for (int i = 1; i < 61; i++) {
- st[i] = st[i - 1] << 1;
- ODIN += st[i];
- }
- cin >> n >> q;
- for (int i = 0; i < n; i++) {
- cin >> a[i];
- b[i] = a[i];
- }
- t.init();
- for (int I = 0; I < q; I++) {
- cin >> type >> op;
- /*int tp = rand() % 2;
- if (tp == 0) {
- type = "upd";
- }
- else {
- type = "get";
- }
- int tp2 = rand() % 3;
- if (tp2 == 0) {
- op = "and";
- }
- if (tp2 == 1) {
- op = "or";
- }
- if(tp2 == 3){
- op = "xor";
- }*/
- if (type == "upd") {
- cin >> l >> r >> x;
- /*l = rand() % n + 1;
- r = rand() % n + 1;
- x = rand();
- if (r < l) {
- swap(l, r);
- }
- cout << type << " " << op << " " << l << " " << r << "\n";
- */
- if (op == "and") {
- if (n <= 1000 && q <= 1000) {
- l--;
- r--;
- for (int i = l; i <= r; i++) {
- b[i] = b[i] & x;
- }
- }else t.ands(l, r, x);
- }
- if (op == "or") {
- if (n <= 1000 && q <= 1000) {
- l--;
- r--;
- for (int i = l; i <= r; i++) {
- b[i] = b[i] | x;
- }
- }else t.ors(l, r, x);
- }
- if (op == "xor") {
- if (n <= 1000 && q <= 1000) {
- l--;
- r--;
- for (int i = l; i <= r; i++) {
- b[i] = b[i] ^ x;
- }
- }else t.xors(l, r, x);
- }
- }
- else {
- /*l = rand() % n + 1;
- r = rand() % n + 1;
- if (r < l) {
- swap(l, r);
- }*/
- cin >> l >> r;
- if (op == "and") {
- long long a1 = t.get_a(l, r);
- if (n <= 1000 && q <= 1000) {
- l--;
- r--;
- long long ans = b[l];
- for (int i = l + 1; i <= r; i++) {
- ans = ans & b[i];
- }
- a1 = ans;
- }
- cout << a1 << "\n";
- }
- if (op == "or") {
- long long a1 = t.get_o(l, r);
- if (n <= 1000 && q <= 1000) {
- l--;
- r--;
- long long ans = b[l];
- for (int i = l + 1; i <= r; i++) {
- ans = ans | b[i];
- }
- a1 = ans;
- }
- cout << a1 << "\n";
- }
- if (op == "xor") {
- long long a1 = t.get_x(l, r);
- if (n <= 1000 && q <= 1000) {
- l--;
- r--;
- long long ans = b[l];
- for (int i = l + 1; i <= r; i++) {
- ans = ans ^ b[i];
- }
- a1 = ans;
- }
- cout << a1 << "\n";
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement