1. 程式人生 > >[Luogu] 開關

[Luogu] 開關

freopen -- ++ () pan char 開關 names oid

https://www.luogu.org/problemnew/show/P3870

線段樹區間翻轉 + 區間查詢

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;
const int N = 1e5 + 10;

#define yxy getchar()
#define lson jd << 1
#define rson jd << 1 | 1

#define
RR freopen("gg.in", "r", stdin) int n, Ty, ans; int L[N << 2], R[N << 2], life[N << 2], F[N << 2], size[N << 2]; inline int read() { int x = 0, f = 1; char c = yxy; while(c < 0 || c > 9) {if(c == -) f = -1; c = yxy;} while(c >= 0 && c <=
9) x = x * 10 + c - 0, c = yxy; return x * f; } void Build_tree(int l, int r, int jd) { L[jd] = l; R[jd] = r; size[jd] = r - l + 1; if(l == r) return ; int mid = (l + r) >> 1; Build_tree(l, mid, lson); Build_tree(mid + 1, r, rson); } void down(int jd) { F[lson]
+= (F[jd] % 2); F[rson] += (F[jd] % 2); if(F[jd] % 2) life[lson] = size[lson] - life[lson], life[rson] = size[rson] - life[rson]; F[jd] = 0; } void Sec_G(int l, int r, int jd, int x, int y) { if(x <= l && r <= y) { F[jd] ++; life[jd] = size[jd] - life[jd]; return ; } if(F[jd]) down(jd); int mid = (l + r) >> 1; if(x <= mid) Sec_G(l, mid, lson, x, y); if(y > mid) Sec_G(mid + 1, r, rson, x, y); life[jd] = life[lson] + life[rson]; } void Sec_A(int l, int r, int jd, int x, int y) { if(x <= l && r <= y) { ans += life[jd]; return ; } if(F[jd]) down(jd); int mid = (l + r) >> 1; if(x <= mid) Sec_A(l, mid, lson, x, y); if(y > mid) Sec_A(mid + 1, r, rson, x, y); } int main() { n = read(); Ty = read(); Build_tree(1, n, 1); while(Ty --) { int opt = read(), x = read(), y = read(); if(!opt) { // 區間翻轉 Sec_G(1, n, 1, x, y); } else { ans = 0; Sec_A(1, n, 1, x, y); cout << ans << endl; } } return 0; }

[Luogu] 開關