zoukankan      html  css  js  c++  java
  • codevs 1690 开关灯 线段树区间更新 区间查询Lazy

    题目描述 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

     

     
    题意:中文题意
     
    题解:裸的线段树  区间更新 区间查询求和   如果直接更新到叶子节点 线段树就会退化
     lazy 延迟标记  因为只有开灯与关灯两种状态 所以可以%2处理 将累计起来的add  %2处理
    只有当add%2==1时间  才需要向下延迟 并更新下一层的add
     
     
    卡这里卡了很久ORZZZZ
      1 //code by  drizzle
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<algorithm>
      6 #include<vector>
      7 #define ll __int64
      8 #define PI acos(-1.0)
      9 #define mod 1000000007
     10 using namespace std;
     11 int n,m;
     12 int flag,x,y;
     13 struct node
     14 {
     15     int l;
     16     int r;
     17     int add;
     18     int sum;
     19 }tree[400005];
     20 void buildtree(int root,int left,int right)
     21 {
     22     tree[root].l=left;
     23     tree[root].r=right;
     24     tree[root].add=0;
     25     if(left==right)
     26     {
     27         tree[root].sum=0;
     28         return;
     29     }
     30     int mid=(left+right)>>1;
     31     buildtree(root<<1,left,mid);
     32     buildtree(root<<1|1,mid+1,right);
     33     tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
     34 }
     35 void pushdown(int root,int m)
     36 {
     37     tree[root<<1].add++;
     38     tree[root<<1].add=tree[root<<1].add%2;
     39     tree[root<<1|1].add++;
     40     tree[root<<1|1].add=tree[root<<1|1].add%2;
     41     tree[root<<1].sum=(m-(m>>1))-tree[root<<1].sum;
     42     tree[root<<1|1].sum=(m>>1)-tree[root<<1|1].sum;
     43     tree[root].add=0;
     44 }
     45 void updata(int c,int left,int right,int root)
     46 {
     47     if(tree[root].l==left&&tree[root].r==right)
     48     {
     49          tree[root].add++;
     50          tree[root].add=tree[root].add%2;
     51          tree[root].sum=right-left+1-tree[root].sum;
     52         return ;
     53     }
     54     if(tree[root].l==tree[root].r)
     55         return ;
     56     if(tree[root].add)
     57         pushdown(root,tree[root].r-tree[root].l+1);
     58     int mid=(tree[root].l+tree[root].r)>>1;
     59     if(right<=mid)
     60     updata(c,left,right,root<<1);
     61     else
     62     {
     63         if(left>mid)
     64             updata(c,left,right,root<<1|1);
     65         else
     66         {
     67             updata(c,left,mid,root<<1);
     68             updata(c,mid+1,right,root<<1|1);
     69         }
     70     }
     71     tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
     72 }
     73 int query(int root ,int left,int right)
     74 {
     75     if(tree[root].l==left&&tree[root].r==right)
     76     {
     77         return tree[root].sum;
     78     }
     79     if(tree[root].add)
     80         pushdown(root,tree[root].r-tree[root].l+1);
     81     int mid=(tree[root].l+tree[root].r)>>1;
     82     if(right<=mid)
     83          return query(root<<1,left,right);
     84     else
     85     {
     86         if(left>mid)
     87          return query(root<<1|1,left,right);
     88         else
     89            return (query(root<<1,left,mid)+query(root<<1|1,mid+1,right));
     90     }
     91 }
     92 int main()
     93 {
     94     while(scanf("%d %d",&n,&m)!=EOF)
     95     {
     96         buildtree(1,1,n);
     97         for(int i=1;i<=m;i++)
     98         {
     99             scanf("%d %d %d",&flag,&x,&y);
    100             if(flag==0)
    101             {
    102                 updata(1,x,y,1);
    103             }
    104             else
    105             {
    106                 printf("%d
    ",query(1,x,y));
    107             }
    108         }
    109     }
    110     return 0;
    111 }
  • 相关阅读:
    Android开发(十五)-Service和BroadcastReceiver
    Android开发(十四)-ContentProvider数据共享
    Android开发(十三)-图形与图像处理
    Android开发(十二)-Android应用资源
    Android开发(十一)-Intent和IntentFilter通信
    Android开发(十)-Activity和Fragment
    Android开发(九)-事件机制
    模拟面试
    二叉堆
    面试
  • 原文地址:https://www.cnblogs.com/hsd-/p/5692971.html
Copyright © 2011-2022 走看看