Codeforces 915E 线段树动态开点

#include <bits/stdc++.h>

namespace fastIO {
    #define BUF_SIZE 10000000
    //fread -> read
    bool IOerror = 0;
    inline char nc() {
        static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
        if(p1 == pend) {
            p1 = buf;
            pend = buf + fread(buf, 1, BUF_SIZE, stdin);
            if(pend == p1) {
                IOerror = 1;
                return -1;
            }
        }
        return *p1++;
    }
    inline bool blank(char ch) {
        return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
    }
    inline void read(int &x) {
        char ch;
        while(blank(ch = nc()));
        if(IOerror)
            return;
        for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
    }
    #undef BUF_SIZE
};
using namespace fastIO;
using namespace std;
#define ALL(X) X.begin(),X.end()
#define RALL(X) X.rbegin(),X.rend()
#define SZ(X) ((int)X.size())
#define mp make_pair
#define mt make_tuple
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using ll = long long ;
using ld = long double;
const int N = 7E5 + 7, M = 3E5 + 7;
int A[N<<2], B[N<<2];
bool vis[N<<2], C[N<<2];
struct node
{
    int l, r, k;
}Q[M];
vector<int>a;
inline void pushup(int rt){A[rt] = A[rt<<1] + A[rt<<1|1];}
void pushdown(int rt)
{
    if(vis[rt]) {
        A[rt<<1] = B[rt<<1] * C[rt];
        A[rt<<1|1] = B[rt<<1|1] * C[rt];
        C[rt<<1] = C[rt<<1|1] = C[rt];
        vis[rt<<1] = vis[rt<<1|1] = 1;
        vis[rt] = 0;
    }
}
void build(int l, int r, int rt)
{
    C[rt] = 1;
    if(l == r) {
        B[rt] = A[rt] = a[l] - a[l-1];
        return ;
    }
    int mid = (l + r) >> 1;
    build(lson), build(rson);
    A[rt] = A[rt<<1] + A[rt<<1|1];
    B[rt] = B[rt<<1] + B[rt<<1|1];
}
void update(int L, int R, int k, int l, int r, int rt)
{
    if(L <= l && r <= R) {
        C[rt] = k;
        vis[rt] = 1;
        A[rt] = B[rt] * k ;
        return ;
    }
    pushdown(rt);
    int mid = (l + r) >> 1;
    if(L <= mid) update(L, R, k, lson);
    if(R > mid) update(L, R, k, rson);
    pushup(rt);
}
int main()
{
    int n, q, cnt = 0;
    read(n); read(q);
    for(int i = 0;i < q;i ++) {
        int l, r, k;
        read(l), read(r), read(k);
        Q[i] = {l, r, --k};
        a.push_back(l-1), a.push_back(r);
    }
    a.push_back(n);
    a.push_back(0);
    sort(ALL(a));
    a.erase(unique(ALL(a)), a.end());
    cnt = SZ(a) - 1;
    build(1, cnt, 1);
    for(int i = 0;i < q;i ++) {
        int l, r;
        l = lower_bound(ALL(a), Q[i].l) - a.begin();
        r = lower_bound(ALL(a), Q[i].r) - a.begin();
        update(l, r, Q[i].k, 1, cnt, 1);
        //cout << l << " " << r << endl;
        printf("%d\n",A[1]);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值