zoukankan      html  css  js  c++  java
  • 洛谷 P2574 XOR的艺术(线段树 区间异或 区间求和)

    To 洛谷.2574 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

    思路:

      线段树,只需要把Lazy标记部分改一下。

    代码:

     1 #include<cstdio>
     2 using namespace std;
     3 const int N=200005;
     4 
     5 int n,m,Sum[N<<2],Lazy[N<<2];
     6 //char str[N];
     7 
     8 void read(int &now)
     9 {
    10     now=0;char c=getchar();
    11     while(c<'0'||c>'9')c=getchar();
    12     while(c>='0'&&c<='9')now=now*10+c-'0',c=getchar();
    13 }
    14 
    15 void PushUp(int rt)
    16 {
    17     Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1];
    18 }
    19 void PushDown(int rt,int m)
    20 {
    21     if(Lazy[rt])
    22     {
    23         Lazy[rt<<1]^=1;
    24         Lazy[rt<<1|1]^=1;
    25         Sum[rt<<1]=(m-(m>>1))-Sum[rt<<1];//异或(取反),将原先状态全部翻转 
    26         Sum[rt<<1|1]=(m>>1)-Sum[rt<<1|1];//该区间一共(r-l+1)>>1 个元素,减去自己即为异或后状态 
    27         Lazy[rt]=0;
    28     }
    29 }
    30 void Build(int l,int r,int rt)
    31 {
    32     Lazy[rt]=0;
    33     if(l==r)
    34     {
    35         int a;
    36         scanf("%1d",&a);
    37         Sum[rt]= a?1:0;
    38         //Sum[rt]= str[l]=='1'?1:0;
    39         return;
    40     }
    41     int m=(l+r)>>1;
    42     Build(l,m,rt<<1);
    43     Build(m+1,r,rt<<1|1);
    44     PushUp(rt);
    45 }
    46 void ModifyXor(int l,int r,int rt,int L,int R)
    47 {
    48     if(L<=l && r<=R)
    49     {
    50         Lazy[rt]^=1;
    51         Sum[rt]=r-l+1-Sum[rt];
    52         return;
    53     }
    54     PushDown(rt,r-l+1);
    55     int m=(l+r)>>1;
    56     if(L<=m) ModifyXor(l,m,rt<<1,L,R);
    57     if(m<R) ModifyXor(m+1,r,rt<<1|1,L,R);
    58     PushUp(rt);
    59 }
    60 int QuerySum(int l,int r,int rt,int L,int R)
    61 {
    62     if(L<=l && r<=R) return Sum[rt];
    63     PushDown(rt,r-l+1);
    64     int m=(l+r)>>1,res=0;
    65     if(L<=m) res+=QuerySum(l,m,rt<<1,L,R);
    66     if(m<R) res+=QuerySum(m+1,r,rt<<1|1,L,R);
    67     return res;
    68 }
    69 
    70 int main()
    71 {
    72     read(n);read(m);//scanf("%s",str+1);
    73     Build(1,n,1);
    74     for(int i=1;i<=m;i++)
    75     {
    76         int p,l,r;
    77         read(p);read(l);read(r);
    78         if(p)
    79           printf("%d
    ",QuerySum(1,n,1,l,r));
    80         else
    81           ModifyXor(1,n,1,l,r);
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    Python3爬虫系列:理论+实验+爬取妹子图实战
    虚机安装后无网卡、网卡驱动
    Linux运维工程师面试题整理
    睡眠或者重启windows,无法ssh连接或者pingVMware的虚机
    W10: Warning: Changing a readonly file使用vi/vim报错问题解决
    keyboard-interactive authentication with the ssh2 server failed 的SecureCRT报错解决
    公网访问内网实现(内网穿透)
    Linux内网时钟同步问题(ntp和chrony)
    xshell的快捷复制粘贴设置
    Linux中shell去除空行的几种方法
  • 原文地址:https://www.cnblogs.com/SovietPower/p/6889105.html
Copyright © 2011-2022 走看看