洛谷 P1840 【Color the Axis_NOI导刊2011提高(05)】 题解

时间:2019-07-12
本文章向大家介绍洛谷 P1840 【Color the Axis_NOI导刊2011提高(05)】 题解,主要包括洛谷 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\n",ask_color_tree(1,1,n,1,n));  //可以不要,直接输出t[1].sum
84     }
85     I_copy_the_answer //你就别抄这个代码了吧 
86 }

原文地址:https://www.cnblogs.com/zsx6/p/11174399.html