码迷,mamicode.com
首页 > 其他好文 > 详细

Codevs_1690_开关灯(线段树)

时间:2016-04-26 18:52:45      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:

描述


http://codevs.cn/problem/1690/

一排共 n 个灯,起初都是关着的,现在有 m 次操作. 0 开头的操作代表将 l ~ r 的开关按一遍,1 开头的操作代表询问 l ~ r 共多少个开着的灯.

 

分析 


刚开始想的是用 0 , 1 , -1 分别代表区间都是关着的,都是开着的,有开的又有关的,跟新和查询的时候都是查找到非 -1 的区间再做处理,但是 TLE 了.

想一下如果灯是 1 0 1 0 1 0 1 0 1...这样排列的,那就退化得不成样子了.

所以用 on 和 off 分别代表区间内开着的和关着的等的数量,如果按开关,就把这两个值交换.

最后可以不用 off ,只用一个 on ,可以通过区间长度进行计算.

 

#include<cstdio>

const int maxn=100005;
struct node { int l,r; int on;bool d; }a[3*maxn];
int n,m;

void build_tree(int l,int r,int k)
{
    a[k].l=l; a[k].r=r; a[k].on=0; a[k].d=false;
    if(l==r) return;
    int mid=l+(r-l)/2;
    build_tree(l,mid,2*k);
    build_tree(mid+1,r,2*k+1);
}

inline void turn(int k)
{
    a[k].on=(a[k].r-a[k].l+1)-a[k].on;
    a[k].d^=true;
}

void update(int l,int r,int k)
{
    if(a[k].l==l&&a[k].r==r)
    {
        turn(k);
        return;
    }
    if(a[k].d)
    {
        turn(2*k);
        turn(2*k+1);
        a[k].d=false;
    }
    int mid=a[k].l+(a[k].r-a[k].l)/2;
    if(r<=mid) update(l,r,2*k);
    else if(l>mid) update(l,r,2*k+1);
    else { update(l,mid,2*k); update(mid+1,r,2*k+1); }
    a[k].on=a[2*k].on+a[2*k+1].on;
}

int search(int l,int r,int k)
{
    if(a[k].l==l&&a[k].r==r) return a[k].on;
    if(a[k].d)
    {
        turn(2*k);
        turn(2*k+1);
        a[k].d=false;
    }
    int mid=a[k].l+(a[k].r-a[k].l)/2;
    if(r<=mid) return search(l,r,2*k);
    else if(l>mid) return search(l,r,2*k+1);
    else return search(l,mid,2*k)+search(mid+1,r,2*k+1);
}

int main()
{
    scanf("%d%d",&n,&m);
    build_tree(1,n,1);
    
    int qry,l,r;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&qry,&l,&r);
        switch(qry)
        {
            case 0:
                update(l,r,1);
                break;
            case 1:
                printf("%d\n",search(l,r,1));
                break;
        }
    }
    return 0;
}

 

Codevs_1690_开关灯(线段树)

标签:

原文地址:http://www.cnblogs.com/Sunnie69/p/5435903.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!