P2574 XOR的艺术

线段树的区间修改的修改版

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 7;
int tree[N * 4], mark[N * 4];
char str[N];

void push(int l, int r, int i){
  if(mark[i] % 2 == 0){
    mark[i] = 0;
    return;
  }
  int mid = (l + r) >> 1;
  tree[i * 2] = (mid - l + 1) - tree[i * 2];
  tree[i * 2 + 1] = (r - mid) - tree[i * 2 + 1];
  mark[i * 2] += mark[i];
  mark[i * 2 + 1] += mark[i];
  mark[i] = 0;
}

void build(int l, int r, int i){
  tree[i] = 0;
  if(l == r){
    tree[i] = str[l] - '0';
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, i * 2);
  build(mid + 1, r, i * 2 + 1);
  tree[i] = tree[i * 2] + tree[i * 2 + 1];
}

void changr(int l, int r, int i, int x, int y){
  if(x <= l && y >= r){
    mark[i] ++, tree[i] = (r - l + 1) - tree[i];
    return;
  }
  push(l, r, i);
  int mid = (l + r) >> 1;
  if(mid >= x) changr(l, mid, i * 2, x, y);
  if(mid < y) changr(mid + 1, r, i * 2 + 1, x, y);
  tree[i] = tree[i * 2] + tree[i * 2 + 1];
}

int query(int l, int r, int i, int x, int y){
  int ans = 0;
  if(x <= l && r <= y){
    return tree[i];
  }
  int mid = (l + r) >> 1;
  push(l, r, i);
  if(mid >= x) ans += query(l, mid, i * 2, x, y);
  if(mid < y) ans += query(mid + 1, r, i * 2 + 1, x, y);
  return ans;
}

int main(){
  int n, m;
  scanf("%d%d", &n, &m);
  getchar();
  scanf("%s", str + 1);
  build(1, n, 1);
  while(m --){
    int p, l, r;
    scanf("%d%d%d", &p, &l, &r);
    if(p)
      printf("%d\n", query(1, n, 1, l, r));
    else
      changr(1, n, 1, l, r);
  }
  return 0;
}

posted @   feuerwerk  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示