看了一下题解,显然在做无用功啊,而且麻烦了许多,但是这道题真心不难,显然是一个区间修改的题目,然后查询的题目
我的线段树只需要记录一个量:区间和
看了一下其他题解的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 }