zoukankan      html  css  js  c++  java
  • 洛谷P2574 XOR的艺术(线段树)——Chemist

    当线段树遇上无敌位运算!

    还是老套路,线段树维护区间和,一个区间有几个"1"就是这个区间的区间和,同时支持区间修改区间查询,只不过操作从加法变成了异或。主要难点就在更新懒标记那里,详解见代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXX=200010;
    int read()
    {
        int ans=0;
        char ch=getchar(),last=' ';
        while(ch>'9'||ch<'0')
        {last=ch;ch=getchar();}
        while(ch>='0'&&ch<='9')
        {ans=ans*10+ch-'0';ch=getchar();}
        if(last=='-')ans=-ans;
        return ans;
    }
    int n,m,a[MAXX];
    char c[MAXX];
    struct Segment_Tree{
        int l,r,sum,tag;
    }t[4*MAXX];
    void pushup(int p)
    {
        t[p].sum=t[p*2].sum+t[p*2+1].sum;
        //维护区间和,也就是统计区间里有几个"1"
    }
    void pushdown(int p)//下放懒标记
    {
        if(t[p].tag){
            t[p*2].tag^=1;
            t[p*2+1].tag^=1;
            //更新子节点的懒标记
            t[p*2].sum=(t[p*2].r-t[p*2].l+1)-t[p*2].sum;
            //该区间异或1后全部取反,因此"1"的数量等于整个区间长减去原来"1"的数量
            t[p*2+1].sum=(t[p*2+1].r-t[p*2+1].l+1)-t[p*2+1].sum;
            t[p].tag=0;
        }
    }
    void build(int p,int l,int r)
    {
        t[p].l=l;t[p].r=r;
        if(l==r){t[p].sum=a[l];t[p].tag=0;return;}
        int mid=(l+r)/2;
        build(p*2,l,mid);
        build(p*2+1,mid+1,r);
        pushup(p);
    }
    void Xor(int p,int l,int r)
    {
        if(l<=t[p].l&&r>=t[p].r)
        {t[p].sum=(t[p].r-t[p].l+1)-t[p].sum;
        t[p].tag^=1;return;}
        pushdown(p);
        int mid=(t[p].l+t[p].r)/2;
        if(l<=mid)Xor(p*2,l,r);
        if(r>mid)Xor(p*2+1,l,r);
        pushup(p);
    }
    int ask(int p,int l,int r)
    {
        if(l<=t[p].l&&r>=t[p].r)return t[p].sum;
        pushdown(p);
        int mid=(t[p].l+t[p].r)/2;
        int ans=0;
        if(l<=mid)ans+=ask(p*2,l,r);
        if(r>mid)ans+=ask(p*2+1,l,r);
        return ans;
    }
    int main()
    {
        n=read();m=read();
        cin>>c+1;
        for(int i=1;i<=n;i++) 
         a[i]=c[i]-'0';
        build(1,1,n);
        for(int i=1;i<=m;i++){
            int op,l,r;
            op=read();l=read();r=read();
            if(op==0)Xor(1,l,r);
            else printf("%d
    ",ask(1,l,r));
        }
        return 0;
    }
  • 相关阅读:
    jenkins或ansible启动应用不成功日志又不报错
    zookeeper学习(2)----zookeeper和kafka的关系
    缺包与maven
    zookeeper入门(1)---基本概念
    6. kafka序列化和反序列化
    5.Kafka消费者-从Kafka读取数据(转)
    git学习(5)---git stash
    通过getResourceAsStream方法获取项目下的指定资源
    CommandLineParse类(命令行解析类)
    4.kafka生产者---向Kafka中写入数据(转)
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9374039.html
Copyright © 2011-2022 走看看