zoukankan      html  css  js  c++  java
  • 洛谷 P1840 【Color the Axis_NOI导刊2011提高(05)】 题解

    看了一下题解,显然在做无用功啊,而且麻烦了许多,但是这道题真心不难,显然是一个区间修改的题目,然后查询的题目

    我的线段树只需要记录一个量:区间和

    看了一下其他题解的pushdown函数,发现真心写的很麻烦

    这里有一个很巧妙的解法:

    如果这个区域被染成了白棋,那么直接把这个区间总和清零就好了

    然后向下传值,只需要把他的儿子节点sum清零就好了

    那就直接上代码吧

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<queue>
     6 #include<stack>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<algorithm> 
    11 
    12 #define lson i*2,l,mid
    13 #define rson i*2+1,mid+1,r  //宏定义 
    14 #define I_copy_the_answer return 0;
    15 using namespace std;
    16 
    17 int n,m;
    18 struct tree{
    19     int l,r,sum;
    20 }t[1000860];  //线段树最大可能达到四倍空间,因此数组开四倍以上 
    21 
    22 void build_tree(int i,int l,int r)
    23 {
    24     t[i].l=l;  //这东西没什么用,但是查错的时候挺方便的 
    25     t[i].r=r;
    26     if(l==r)
    27     {
    28         t[i].sum=1;  //每一个黑色棋子 
    29         return ;
    30     }
    31     int mid=(l+r)/2;
    32     build_tree(lson);
    33     build_tree(rson);
    34     t[i].sum=t[i*2].sum+t[i*2+1].sum; //这个不多睡了吧 
    35     return ;
    36 }
    37 
    38 int pushdown(int i)   //简短的pushdown 
    39 {
    40     if(!t[i].sum)  //!即取反 0取反即1 
    41     t[i*2].sum=0,t[i*2+1].sum=0;  
    42 }
    43 
    44 void change_tree(int i,int l,int r,int a,int b)
    45 {
    46     if(l>=a&&r<=b)
    47     {
    48         t[i].sum=0;
    49         return ;
    50     }
    51     pushdown(i);  
    52     int mid=(l+r)/2;
    53     if(a<=mid) change_tree(lson,a,b);
    54     if(b>mid) change_tree(rson,a,b);
    55     t[i].sum=t[i*2].sum+t[i*2+1].sum;  
    56     return ;
    57 }
    58 
    59 int ask_color_tree(int i,int l,int r,int a,int b)  //这个函数其实可以不写,输出t[1].sum即可,但是为了演示一下写了出来
    60 {
    61     if(l>=a&&r<=b)
    62     {
    63         return t[i].sum;
    64     }
    65     pushdown(i);  
    66     int mid=(l+r)/2;
    67     int ans=0;
    68     if(a<=mid) ans+=ask_color_tree(lson,a,b);
    69     if(b>mid) ans+=ask_color_tree(rson,a,b);
    70     return ans;
    71 }
    72 
    73 int main()
    74 {
    75     int i,j;
    76     scanf("%d %d",&n,&m);
    77     build_tree(1,1,n);
    78     for(i=1;i<=m;i++)
    79     {
    80         int t1,t2;
    81         scanf("%d %d",&t1,&t2);
    82         change_tree(1,1,n,t1,t2);
    83         printf("%d
    ",ask_color_tree(1,1,n,1,n));  //可以不要,直接输出t[1].sum
    84     }
    85     I_copy_the_answer //你就别抄这个代码了吧 
    86 }
  • 相关阅读:
    [算法]最长的可整合数组的长度
    [算法]在行列都排好序的矩阵中找数
    [算法]在数组中找到出现次数大于N/K的数
    [算法]需要排序的最短子数组长度
    [算法]找到无序数组中最小的K个数
    [算法]“之”字形打印矩阵
    [java]final关键字、finally关键字与finalize()方法
    [算法]旋转矩阵问题(Spiral Matrix)
    [算法]位运算问题之三(实现加减乘除)
    [IDE]Intellij Idea学习整理
  • 原文地址:https://www.cnblogs.com/zsx6/p/11174399.html
Copyright © 2011-2022 走看看