zoukankan      html  css  js  c++  java
  • 洛谷P2574 XOR的艺术 线段树 区间修改 区间求和询问

    洛谷P2574 XOR的艺术
    线段树 区间修改 区间求和询问


    关于线段树的空间问题
    线段树 一般来说都是要四倍空间的,当然你也可以动态开点

    然后我这道题因为姿势不大妙 ,然后空间需要八倍才能过,然后一直RE
    后来我发现了问题所在
    当区间询问 区间修改到达也叶节点 是不用再向下面推标记了的,
    因为lazy 标记表示的是当前这个节点已经处理过了,然后他的儿子还没有处理过,
    因为是叶节点,所以他的儿子自然是不用再处理的,因为叶节点是没有儿子的,所以
    自然就不用再下推标记了

    如果叶节点还下推标记,那就需要八倍空间了
    所以我们先判是不是叶节点 是的话就直接更新 然后就退出
    不是在 下推标记 ,这样空间就稳定是 4 倍了

      1 #include <cstdio>
      2 #include <cmath>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <string>
      6 #include <algorithm>
      7 #include <iomanip>
      8 #include <iostream> 
      9 using namespace std ; 
     10 
     11 const int maxn = 200011 ; 
     12 char s[maxn] ; 
     13 struct node{
     14     int l,r,sum,xr ; 
     15 }tree[4*maxn]; 
     16 int n,Q,type,ans ; 
     17 
     18 inline int read() 
     19 {
     20     char ch = getchar() ; 
     21     int x = 0 ,f = 1 ; 
     22     while(ch<'0'||ch>'9') { if(ch=='-') f = -1 ; ch = getchar() ; } 
     23     while(ch>='0'&&ch<='9') { x = x*10+ch-48 ; ch = getchar() ; } 
     24     return x*f ; 
     25 } 
     26 
     27 inline void pushup(int root) 
     28 {
     29     tree[root].sum = tree[root*2].sum + tree[root*2+1].sum ; 
     30 }
     31 
     32 inline void pushdown(int root) 
     33 {
     34     tree[root*2].xr^=1 ; 
     35     tree[root*2].sum = ( tree[root*2].r - tree[root*2].l+1 ) -tree[root*2].sum ;  
     36     tree[root*2+1].xr^=1 ;  
     37     tree[root*2+1].sum = (tree[root*2+1].r - tree[root*2+1].l +1 ) - tree[root*2+1].sum ; 
     38     tree[root].xr = 0 ; 
     39 }
     40 
     41 inline void updata(int l,int r,int root) 
     42 {
     43     if(tree[root].l==l&&tree[root].r==r) 
     44     {
     45         tree[root].sum = (tree[root].r - tree[root].l + 1 ) - tree[root].sum ; 
     46         tree[root].xr^=1 ; 
     47         return ; 
     48     }
     49     
     50     if(tree[root].xr) pushdown(root) ; 
     51     
     52     int mid = ( tree[root].l + tree[root].r ) /2 ; 
     53     if( r<=mid ) updata(l,r,root*2) ; 
     54     else if(l>mid) updata(l,r,root*2+1) ; 
     55     else {
     56         updata(l,mid,root*2) ; 
     57         updata(mid+1,r,root*2+1) ; 
     58     }
     59     pushup(root) ; 
     60 }
     61 
     62 inline int query(int l,int r,int root) 
     63 { 
     64     if(tree[root].l==l&&tree[root].r==r) 
     65         return tree[root].sum ; 
     66         
     67     if(tree[root].xr) pushdown(root) ;              //  先判断是否为叶节点然后再  下推标记   
     68         
     69     int mid = ( tree[root].l + tree[root].r ) /2 ; 
     70     if( r<=mid ) return query(l,r,root*2) ; 
     71     else if(l>mid) return query(l,r,root*2+1) ; 
     72     else{
     73         int ans = 0 ; 
     74         ans+=query(l,mid,root*2) ; 
     75         ans+=query(mid+1,r,root*2+1) ; 
     76         return ans ; 
     77     } 
     78     
     79 }
     80 
     81 inline void build(int l,int r,int root) 
     82 {
     83     tree[root].l = l ; 
     84     tree[root].r = r ; 
     85     if(l==r) 
     86     {
     87         tree[root].sum = s[ l ] - 48 ;   tree[root].xr = 0 ; 
     88         return ; 
     89     }
     90     int mid = (l+r) / 2 ; 
     91     build(l,mid,root*2) ; 
     92     build(mid+1,r,root*2+1) ; 
     93     pushup(root) ; 
     94 }
     95 
     96 int main() 
     97 {
     98     n = read() ; Q = read() ; 
     99     scanf("%s",s+1) ; 
    100     build(1,n,1) ;   
    101     int x,y ; 
    102     for(int i=1;i<=Q;i++) 
    103     {
    104         type = read() ;  x = read() ; y = read() ; 
    105         if(type==0) 
    106             updata(x,y,1) ; 
    107         else 
    108         {
    109             ans = query(x,y,1) ; 
    110             printf("%d
    ",ans) ; 
    111         }
    112     }
    113     return 0 ; 
    114 }
  • 相关阅读:
    css 响应式布局
    【nodejs】async
    vue移动appUI框架搭建-选取mintUI
    浅谈开发流程_敏捷开发流程_迭代流程的理解
    一篇业务需求上的数据处理问题--后台API只返回四个字段ABCD,现在数据量较大有20万条,一列上要展示ABCDABCDABCD这么些字段
    vue列表鼠标滚动翻页(数据量较大,几千万条数据,因此要滚动翻页,为了性能良好,鼠标滚动时发送请求页码page++),网上找不到自己写了一个,
    app移动端 rem和px的换算
    vue搜索关键字字体高亮, map映射新数组,replace替换,font字体样式
    vue文字截取方法 :title | filterFun方法过滤
    什么是正则表达式?
  • 原文地址:https://www.cnblogs.com/third2333/p/7085193.html
Copyright © 2011-2022 走看看