zoukankan      html  css  js  c++  java
  • P2574 XOR的艺术

    题目描述

    AKN觉得第一题太水了,不屑于写第一题,所以他又玩起了新的游戏。在游戏中,他发现,这个游戏的伤害计算有一个规律,规律如下

    1、 拥有一个伤害串为长度为n的01串。

    2、 给定一个范围[l,r],伤害为伤害串的这个范围内中1的个数

    3、 会被随机修改伤害串中的数值,修改的方法是把[l,r]中的所有数xor上1

    AKN想知道一些时刻的伤害,请你帮助他求出这个伤害

    输入输出格式

    输入格式:

    第一行两个数n,m,表示长度为n的01串,有m个时刻

    第二行一个长度为n的01串,为初始伤害串

    第三行开始m行,每行三个数p,l,r

    若p为0,则表示当前时刻改变[l,r]的伤害串,改变规则如上

    若p为1,则表示当前时刻AKN想知道[l,r]的伤害

    输出格式:

    对于每次询问伤害,输出一个数值伤害,每次询问输出一行

    输入输出样例

    输入样例#1: 
    10 6
    1011101001
    0 2 4
    1 1 5
    0 3 7
    1 1 10
    0 1 4
    1 2 6
    
    输出样例#1: 
    3
    6
    1
    

    说明

    样例解释:

    1011101001

    1100101001

    询问[1,5]输出3

    1111010001

    询问[1,10]输出6

    0000010001

    询问[2,6]输出1

    数据范围:

    10%数据2≤n,m≤10

    另有30%数据2≤n,m≤2000

    100%数据2≤n,m≤2*10^5

    By:worcher

    Solution:

      本题其实就是一道线段树的模板,改下$lazy$数组就$OK$了。

      我们知道$1;xor;1=0,;0;xor;1=1$,于是当一段区间$[l,r];xor;1$后,等同于$[l,r]$中的$1$都变为$0$、$0$都变为$1$,那么我们直接维护$sum$表示一段区间的和(即$1$的个数),那么每次修改区间$[l,r]$,等同于$sum=(l-r+1)-sum$(即:更新后的$1$的个数=原区间$0$的个数=区间元素总个数-原本$1$的个数)。然后就是普通的区间修改区间查询了。

    代码:

    #include<bits/stdc++.h>
    #define il inline
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    const int N=2e5+7;
    int n,m,lazy[N<<2],sum[N<<2];
    char s[N];
    il int gi(){
        int a=0;char x=getchar();bool f=0;
        while((x<'0'||x>'9')&&x!='-')x=getchar();
        if(x=='-')x=getchar(),f=1;
        while(x>='0'&&x<='9')a=a*10+x-48,x=getchar();
        return f?-a:a;
    }
    il void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
    il void build(int l,int r,int rt){
        if(l==r){scanf("%1d",&sum[rt]);return;}
        int m=l+r>>1;
        build(lson),build(rson);
        pushup(rt);
    }
    il void pushdown(int rt,int l){
        if(lazy[rt]){
            lazy[rt<<1]^=1,lazy[rt<<1|1]^=1,lazy[rt]=0;
            sum[rt<<1]=(l-(l>>1))-sum[rt<<1],sum[rt<<1|1]=(l>>1)-sum[rt<<1|1];
        }
    }
    il void update(int L,int R,int l,int r,int rt){
        if(L<=l&&R>=r){
            lazy[rt]^=1;
            sum[rt]=(r-l+1)-sum[rt];
            return ;
        }
        pushdown(rt,r-l+1);
        int m=l+r>>1;
        if(L<=m)update(L,R,lson);
        if(m<R)update(L,R,rson);
        pushup(rt);
    }
    il int query(int L,int R,int l,int r,int rt){
        if(L<=l&&r<=R)return sum[rt];
        pushdown(rt,r-l+1);
        int m=l+r>>1,ans=0;
        if(L<=m)ans+=query(L,R,lson);
        if(m<R)ans+=query(L,R,rson);
        return ans;
    }
    int main()
    {
        n=gi(),m=gi();
        build(1,n,1);
        int u,v,w;
        while(m--){
            u=gi(),v=gi(),w=gi();
            if(u)printf("%d
    ",query(v,w,1,n,1));
            else update(v,w,1,n,1);
        }
        return 0;
    }
  • 相关阅读:
    python中创建函数和调用函数
    python中函数的参数
    python 函数中的关键字参数
    python中创建集合
    python中函数文档
    python中函数形式参数、实际参数、位置参数、关键字参数
    python中不可变集合
    我是谁?(程序员版)
    《林阴小路》疏辨
    用户接口常用术语英语德语对照
  • 原文地址:https://www.cnblogs.com/five20/p/8947598.html
Copyright © 2011-2022 走看看