• 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

    思路

    线段树(带一下flag标记)

    代码实现

     1 #include<cstdio>
     2 const int maxn=1e6;
     3 const int maxl=1e6;
     4 inline int min_(int x,int y){return x<y?x:y;}
     5 inline int max_(int x,int y){return x>y?x:y;}
     6 int n,m,l;
     7 int a,b,c;
     8 char ch[maxl];
     9 struct nate{int l,r,s,flag;}t[maxn];
    10 void build(int k,int l,int r){
    11     t[k].l=l,t[k].r=r;
    12     if(l==r){
    13         t[k].s=ch[l-1]=='1'?1:0;
    14         return;
    15     }
    16     int mid=l+r>>1,ls=k<<1,rs=ls+1;
    17     build(ls,l,mid);
    18     build(rs,mid+1,r);
    19     t[k].s=t[ls].s+t[rs].s;
    20 }
    21 void down(int k){
    22     int ls=k<<1,rs=ls+1;
    23     t[ls].s=(t[ls].r-t[ls].l+1)-t[ls].s;
    24     t[rs].s=(t[rs].r-t[rs].l+1)-t[rs].s;
    25     t[ls].flag^=1,t[rs].flag^=1,t[k].flag^=1;;
    26 }
    27 int sum(int k,int l,int r,int al,int ar){
    28     if(l==al&&r==ar) return t[k].s;
    29     if(t[k].flag) down(k);
    30     int ret=0,mid=l+r>>1,ls=k<<1,rs=ls+1;
    31     if(al<=mid) ret+=sum(ls,l,mid,al,min_(ar,mid));
    32     if(ar>mid) ret+=sum(rs,mid+1,r,max_(al,mid+1),ar);
    33     return ret;
    34 }
    35 void change(int k,int l,int r,int al,int ar){
    36     if(l==al&&r==ar){
    37         t[k].s=(t[k].r-t[k].l+1)-t[k].s;
    38         t[k].flag^=1;
    39         return;
    40     }
    41     if(t[k].flag) down(k);
    42     int ret=0,mid=l+r>>1,ls=k<<1,rs=ls+1;
    43     if(al<=mid) change(ls,l,mid,al,min_(ar,mid));
    44     if(ar>mid) change(rs,mid+1,r,max_(al,mid+1),ar);
    45     t[k].s=t[ls].s+t[rs].s;
    46 }
    47 int main(){
    48     scanf("%d%d",&n,&m);
    49     scanf("%s",ch);
    50     build(1,1,n);
    51     for(int i=1;i<=m;i++){
    52         scanf("%d%d%d",&a,&b,&c);
    53         if(a) printf("%d
    ",sum(1,1,n,b,c));
    54         else change(1,1,n,b,c);
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    python 复杂一点的装饰器
    python 装饰器
    python 歌词解析
    ATX 免越狱调试IOS和Android
    OpenCV库文件介绍
    NetEaseGame/ATX 的MD
    带你玩转Visual Studio——带你高效开发
    python 图像识别
    fatal: Authentication failed for又不弹出用户名和密码 解决办法
    lua luna工具库
  • 原文地址:https://www.cnblogs.com/J-william/p/6883298.html
Copyright © 2020-2023  润新知