HOJ 2681 Magic-Pen1

N条单位线段一开始全是白色。有操作使得[l,r]变成黑色或者白色,问最后白色的单位线段的个数。
线段树区间修改,lazy。黑色用0表示,白色用1,这样维护一个sum表示白色个数就可以了。

#include 
#include 
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 111111;
int h , w , n;
int col[maxn<<2];
int sum[maxn<<2];
void PushUp(int rt)
{
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];

}
void PushDown(int rt,int m)
{
       if (col[rt] == 1)
        {
              col[rt<<1] = col[rt<<1|1] = col[rt];
              sum[rt<<1] = (m - (m >> 1)) * col[rt];
              sum[rt<<1|1] = (m >> 1) * col[rt];
              col[rt] = 0;
       }
       else if(col[rt] == -1)
       {
            col[rt<<1] = col[rt<<1|1] = col[rt];
            sum[rt<<1] = 0;
            sum[rt<<1|1] = 0;
            col[rt] = 0;
       }
}
void build(int l,int r,int rt)
{
       col[rt] = 0;
       sum[rt] = 1;
       if (l == r) return ;
       int m = (l + r) >> 1;
       build(lson);
       build(rson);
       PushUp(rt);
}
void update(int L,int R,int c,int l,int r,int rt)
{
       if (L <= l && r <= R)
        {
              col[rt] = c;
              if(c == 1)
              sum[rt] = c * (r - l + 1);
              else sum[rt] = 0;
              return ;
       }
       PushDown(rt , r - l + 1);
       int m = (l + r) >> 1;
       if (L <= m) update(L , R , c , lson);
       if (R > m) update(L , R , c , rson);
       PushUp(rt);
}
int main()
{
       int  n , m;
       while(~scanf("%d%d",&n,&m))
        {
              build(1 , n , 1);
              while (m --)
              {
                     int a , b , c;
                     scanf("%d%d%d",&a,&b,&c);
                     if(c == 1)
                     update(a , b , -1 , 1 , n , 1);
                     else
                     update(a , b , 1 , 1 , n , 1);
              }
              printf("%d\n",sum[1]);
       }
       return 0;
}

你可能感兴趣的:(线段树)