• 洛谷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)

    思路:这是一道跟洛谷(P2574)思路类似的一道题目,唯一不同的就是这道题需要建树,因为初始值不都是(0),然后对于此题,区间修改操作就是区间异或运算,区间查询就是查询区间中(1)的个数,然后用线段树维护区间中(1)的个数即可。

    代码:

    #include<cstdio>
    #include<cctype>
    #define maxn 200007
    #define ls rt<<1
    #define rs rt<<1|1
    using namespace std;
    int n,m,sum[maxn<<2],lazy[maxn<<2];
    inline int qread() {
      char c=getchar();int num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';
      return num*f;
    }
    inline void pushup(int rt) {
      sum[rt]=sum[ls]+sum[rs];
    }
    void build(int rt, int l, int r) {
      if(l==r) {
        scanf("%1d",&sum[rt]);
        return;
      }
      int mid=(l+r)>>1;
      build(ls,l,mid);
      build(rs,mid+1,r);
      pushup(rt);
    }
    inline void pushdown(int rt, int len) {
      if(lazy[rt]) {
        lazy[ls]^=1;
        lazy[rs]^=1;
        sum[ls]=(len-(len>>1))-sum[ls];
        sum[rs]=(len>>1)-sum[rs];
        lazy[rt]=0;
      }
    }
    void modify(int rt, int l, int r, int L, int R) {
      if(L>r||R<l) return;
      if(L<=l&&r<=R) {
        lazy[rt]^=1;
        sum[rt]=r-l+1-sum[rt];
        return;
      }
      pushdown(rt,r-l+1);
      int mid=(l+r)>>1;
      modify(ls,l,mid,L,R),modify(rs,mid+1,r,L,R);
      pushup(rt);
    }
    int csum(int rt, int l, int r, int L, int R) {
      if(L>r||R<l) return 0;
      if(L<=l&&r<=R) return sum[rt];
      pushdown(rt,r-l+1);
      int mid=(l+r)>>1;
      return csum(ls,l,mid,L,R)+csum(rs,mid+1,r,L,R);
    }
    int main() {
      n=qread(),m=qread();
      build(1,1,n);
      for(int i=1,k,l,r;i<=m;++i) {
        k=qread(),l=qread(),r=qread();
        if(!k) modify(1,1,n,l,r);
        else printf("%d
    ",csum(1,1,n,l,r));
      }
      return 0;
    }
    
  • 相关阅读:
    Java字符串跟ASCII码互转
    java 一款可以与ssm框架完美整合的web报表控件
    使用<c:set>标签配置项目路径
    Linux下部署tomcat及tomcat war包应用程序
    支付宝app支付服务端流程
    文本数据增量导入到mysql
    java 读取mysql中数据 并取出
    实现读取文本数据,在将数据导入mysql
    给一个整形数组,给出一个值,当这个值是数组某些数字的和,求出数组下标的值
    文本数据和mysql 里面的数据比较
  • 原文地址:https://www.cnblogs.com/grcyh/p/10172908.html
Copyright © 2020-2023  润新知