Physical Education Lessons(线段树动态开点)

This year Alex has finished school, and now he is a first-year student of Berland State University. For him it was a total surprise that even though he studies programming, he still has to attend physical education lessons. The end of the term is very soon, but, unfortunately, Alex still hasn’t attended a single lesson!
Since Alex doesn’t want to get expelled, he wants to know the number of working days left until the end of the term, so he can attend physical education lessons during these days. But in BSU calculating the number of working days is a complicated matter:
There are n days left before the end of the term (numbered from 1 to n), and initially all of them are working days. Then the university staff sequentially publishes q orders, one after another. Each order is characterised by three numbers l, r and k:
If k = 1, then all days from l to r (inclusive) become non-working days. If some of these days are made working days by some previous order, then these days still become non-working days;
If k = 2, then all days from l to r (inclusive) become working days. If some of these days are made non-working days by some previous order, then these days still become working days.
Help Alex to determine the number of working days left after each order!

给你n,q,原本区间1到n都是1,一共q个操作,如果1操作,则将区间中的数字都改为0,2操作把区间中数字都改为1。刚开始想的是线段树离散化一下,但是一直wa,水平有问题吧。然后看到大家都是用动态开点写的,然后就也比着写了下。感觉写起来代码很简便,比离散化简单多了。但是数组应该开多大不清楚,有的说数组能开多大就开多大,emmm,刚开始我没听,还是按照线段树的开,于是一直MLE,后来就改了下数组大小就过了。一下午结果就改了个数组大小,很是自闭。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 15e6;
int n, q, root, seg[maxn], lazy[maxn], le[maxn], ri[maxn], cnt;

inline void PushUp(int cur)
{
    seg[cur] = seg[le[cur]]+seg[ri[cur]];
}

inline void PushDown(int l, int r, int cur)
{
    if(lazy[cur] == -1) return ;
    int mid = (l+r)>>1;
    if(0 == le[cur])    le[cur] = ++cnt;
    seg[le[cur]] = lazy[cur]*(mid-l+1); lazy[le[cur]] = lazy[cur];
    if(0 == ri[cur])    ri[cur] = ++cnt;
    seg[ri[cur]] = lazy[cur]*(r-mid); lazy[ri[cur]] = lazy[cur];
    lazy[cur] = -1;
}

void update(int l, int r, int L, int R, int &cur, int val)
{
    if(cur == 0)    cur = ++cnt;
    if(l <= L && R <= r)
    {
        seg[cur] = (R-L+1)*val;
        lazy[cur] = val;
        return ;
    }
    PushDown(L, R, cur);
    int mid = (L+R)>>1;
    if(l <= mid)    update(l, r, L, mid, le[cur], val);
    if(r > mid)    update(l, r, mid+1, R, ri[cur], val);
    PushUp(cur);
}

int main()
{
    scanf("%d%d", &n, &q);
    memset(lazy, -1, sizeof(lazy));
    update(1, n, 1, n, root, 1);
    while(q--)
    {
        int l, r, op;
        scanf("%d%d%d", &l, &r, &op);
        update(l, r, 1, n, root, op == 2);
        printf("%d\n", seg[root]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40788897/article/details/99705852