【cf915】E. Physical Education Lessons(线段树)

传送门

简单的线段树区间修改区间查询,但是因为数据范围过大,所以采用动态开点的方法(注意一下空间问题)。
也可以直接对询问区间的端点离散化然后建树,这种方法时间复杂度和空间复杂度都比较优秀。
给出动态开点的代码:

/*
 * Author:  heyuhhh
 * Created Time:  2019/11/12 19:33:21
 */
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 4e5 + 5;
 
int n, q;
int tot;
int rt[1];
int lc[N * 40], rc[N * 40], sum[N * 40], lz[N * 40];
 
void push_up(int o) {
    sum[o] = sum[lc[o]] + sum[rc[o]];    
}
void push_down(int o, int l, int r) {
    if(lz[o] != -1) {
        if(!lc[o]) lc[o] = ++tot;
        if(!rc[o]) rc[o] = ++tot;
        int mid = (l + r) >> 1;
        sum[lc[o]] = (mid - l + 1) * lz[o];
        lz[lc[o]] = lz[o];
        sum[rc[o]] = (r - mid) * lz[o];
        lz[rc[o]] = lz[o];
        lz[o] = -1;
    }   
}
void upd(int &o, int l, int r, int L, int R, int v) {
    if(!o) o = ++tot;
    if(L <= l && r <= R) {
        if(v == 0) sum[o] = lz[o] = 0;
        else sum[o] = r - l + 1, lz[o] = 1;
        return;
    }
    push_down(o, l, r);
    int mid = (l + r) >> 1;
    if(L <= mid) upd(lc[o], l, mid, L, R, v);
    if(R > mid) upd(rc[o], mid + 1, r, L, R, v);
    push_up(o);
}
 
void run(){
    memset(lz, -1, sizeof(lz));
    while(q--) {
        int l, r, k; cin >> l >> r >> k;
        if(k == 1) upd(rt[0], 1, n, l, r, 1);
        else upd(rt[0], 1, n, l, r, 0);
        int ans = n - sum[rt[0]];
        cout << ans << '\n';
    }
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n >> q) run();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/heyuhhh/p/11845796.html
今日推荐