zoukankan      html  css  js  c++  java
  • codevs1690 开关灯(线段树)

    1690 开关灯

     

    USACO

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 钻石 Diamond
     
     
    题目描述 Description

        YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人陆续按下开关,这些开关可以改变从第i盏灯到第j盏灯的状态,现在YYX想知道,从第x盏灯到第y盏灯中有多少是亮着的(1<=i,j,x,y<=N)

    输入描述 Input Description
    第 1 行: 用空格隔开的两个整数N和M
    第 2..M+1 行: 每行表示一个操作, 有三个用空格分开的整数: 指令号(0代表按下开关,1代表询问状态), x 和 y 
    输出描述 Output Description

    第 1..询问总次数 行:对于每一次询问,输出询问的结果

    样例输入 Sample Input

    4 5
    0 1 2
    0 2 4
    1 2 3
    0 2 4
    1 1 4

    样例输出 Sample Output
    1
    2
     
    数据范围及提示 Data Size & Hint

    一共4盏灯,5个操作,下面是每次操作的状态(X代表关上的,O代表开着的):

    XXXX -> OOXX -> OXOO -> 询问1~3 -> OOXX -> 询问1~4

     
    /*
    这道题数据比较强啊 
    每次更新答案=当前区间总数-当前答案。
    标记取反。 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 100005
    
    using namespace std;
    int n,m,x,y,z;
    struct node
    {
        int l,r,sum,dis,flag;
    }tre[maxn<<2];
    
    inline int init()
    {
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    void build(int now,int l,int r)
    {
        tre[now].l=l;tre[now].r=r;tre[now].sum=r-l+1;
        if(l==r) return;
        int mid=(l+r)>>1;
        build(now<<1,l,mid);build(now<<1|1,mid+1,r);
    }
    
    void down(int now)
    {
        tre[now<<1].flag^=1;
        tre[now<<1|1].flag^=1;
        tre[now<<1].dis=tre[now<<1].sum-tre[now<<1].dis;
        tre[now<<1|1].dis=tre[now<<1|1].sum-tre[now<<1|1].dis;
        tre[now].flag=0;
    }
    
    void change(int now,int l,int r)
    {
        if(tre[now].l==l&&tre[now].r==r)
        {
            tre[now].flag^=1;
            tre[now].dis=tre[now].sum-tre[now].dis;
            return;
        }
        if(tre[now].flag) down(now);
        int mid=(tre[now].l+tre[now].r)>>1;
        if(l>mid) change(now<<1|1,l,r);
        else if(r<=mid) change(now<<1,l,r);
        else
        {
            change(now<<1,l,mid);
            change(now<<1|1,mid+1,r);
        }
        tre[now].dis=tre[now<<1].dis+tre[now<<1|1].dis;
    }
    
    int query(int now,int l,int r)
    {
        if(tre[now].l==l&&tre[now].r==r) return tre[now].dis;
        if(tre[now].flag) down(now);
        int mid=(tre[now].l+tre[now].r)>>1; 
        if(l>mid) return query(now<<1|1,l,r);
        else if(r<=mid) return query(now<<1,l,r);
        else return query(now<<1,l,mid)+query(now<<1|1,mid+1,r);
    }
    
    int main()
    {
        n=init();m=init();
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            x=init();y=init();z=init();
            if(!x) change(1,y,z);
            else printf("%d
    ",query(1,y,z));
        }    
        return 0;
    }
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    To My Girlfriend (DP)
    A Simple Nim (SG打表找规律)
    A Boring Question (打表)
    A Simple Chess (Lucas组合数 + 容斥)
    World is Exploding (容斥 + 统计)
    Two (DP)
    K-wolf Number (数位DP)
    Interesting (manacher + 前缀和处理)
    How Many Triangles (极角排序 + 尺取法)
    Divide the Sequence (贪心)
  • 原文地址:https://www.cnblogs.com/L-Memory/p/6800710.html
Copyright © 2011-2022 走看看