zoukankan      html  css  js  c++  java
  • 【CodeVS1690】开关灯

    Description

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

    Input

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

    Output

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

    Sample Input

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

    Sample Output

    1
    2
     

    HINT

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

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

    题解

    线段树,区间改变状态=区间大小-区间和

    #include<iostream>
    #include<cstdio>
    #define N 100010
    using namespace std;
    struct tree
    {
        int L,R;
        int lc,rc;
        int sum,bj;
    }t[N*4];
    int cur,tot;
    void build(int l,int r)
    {
        int cur = ++tot;//.....
    //    int k = cur;
        t[cur].L=l; t[cur].R=r;
        if (r!=l+1)
        {
            t[cur].lc = tot+1;
            build(l,(l+r)/2);
            t[cur].rc = tot+1; //
            build((l+r)/2,r); //
            t[cur].sum=t[t[cur].lc].sum+t[t[cur].rc].sum; //
        } else t[cur].sum=0; //
    }
    void updata(int k)
    {
        t[t[k].lc].bj+=1; t[t[k].rc].bj+=1;
        t[t[k].lc].sum = t[t[k].lc].R-t[t[k].lc].L-t[t[k].lc].sum;
        t[t[k].rc].sum = t[t[k].rc].R-t[t[k].rc].L-t[t[k].rc].sum;
        t[k].bj = 0;
    }
    int query(int k,int ll,int rr)
    {
        if (t[k].L>=ll && t[k].R<=rr) return t[k].sum;
        if (t[k].bj%2 !=0) updata(k);
        int ans=0;
        int mid = (t[k].L+t[k].R)/2;
        if (ll<mid) ans+=query(t[k].lc,ll,rr);
        if (rr>mid) ans+=query(t[k].rc,ll,rr);
        return ans; 
    }
    void change (int k,int ll,int rr)
    {
        if (t[k].L>=ll && t[k].R<=rr)
        {
            t[k].bj++;
            t[k].sum = t[k].R-t[k].L-t[k].sum;
            return ;
        }
        if (t[k].bj%2 !=0) updata(k);
        int mid = (t[k].L+t[k].R)/2;
    /*    if (ll<mid) change(t[k].lc,ll,mid);
        if (rr>mid) change(t[k].rc,mid,rr); 
        不能这样写,因为mid 不一定比rr小!!
        比如说在[1,10) 中修改[2,3)  就把修改范围扩大了!*/
    /*    if (ll<mid) change(t[k].lc,ll,(ll+rr)/2); 
        if (rr>mid) change(t[k].rc,(ll+rr)/2,rr); 
        也不能这样写,比如在[1,20)修改[3,5)
        就变成了在[1,10)修改[3,4)
    */
        if (ll<mid) change(t[k].lc,ll,rr);
        if (rr>mid) change(t[k].rc,ll,rr);//所以还是按模板来吧。。。 
        t[k].sum = t[t[k].lc].sum + t[t[k].rc].sum;
    }
    
    int main()
    {
        int n,m,pd,l,r;
        scanf("%d%d",&n,&m);
        build (1,n+1);
        for (int i=1;i<=m;i++)
        {
            scanf("%d",&pd);
            scanf("%d%d",&l,&r);
            if (pd) 
                printf("%d
    ",query(1,l,r+1));
            else 
                change(1,l,r+1);
        }
    }
  • 相关阅读:
    video兼容ie,ckplayer网页播放器
    边框在2个边,不重叠不接触的情况下是梯形。
    【Unity】关于屏幕自适应的思路
    【Unity】鼠标指向某物体,在其上显示物体的名字等等等等信息
    【C#】关于左移/右移运算符的使用
    【Unity】鼠标点选物体
    Python time和datetime模块
    Python 模块之间的调用
    SaltStack 使用pillar安装配置管理zabbix
    SaltStack 实践课程一
  • 原文地址:https://www.cnblogs.com/liumengyue/p/5494576.html
Copyright © 2011-2022 走看看