求助!玄关!
查看原帖
求助!玄关!
1421850
fuzhu_2011_09_03楼主2024/8/27 20:02

[TJOI2009] 开关

题目描述

现有 nn 盏灯排成一排,从左到右依次编号为:11,22,……,nn。然后依次执行 mm 项操作。

操作分为两种:

  1. 指定一个区间 [a,b][a,b],然后改变编号在这个区间内的灯的状态(把开着的灯关上,关着的灯打开);
  2. 指定一个区间 [a,b][a,b],要求你输出这个区间内有多少盏灯是打开的。

灯在初始时都是关着的。

输入格式

第一行有两个整数 nn 和 mm,分别表示灯的数目和操作的数目。

接下来有 mm 行,每行有三个整数,依次为:cc、aa、bb。其中 cc 表示操作的种类。

  • 当 cc 的值为 00 时,表示是第一种操作。
  • 当 cc 的值为 11 时,表示是第二种操作。

aa 和 bb 则分别表示了操作区间的左右边界。

输出格式

每当遇到第二种操作时,输出一行,包含一个整数,表示此时在查询的区间中打开的灯的数目。

样例 #1

样例输入 #1

4 5
0 1 2
0 2 4
1 2 3
0 2 4
1 1 4

样例输出 #1

1
2

提示

数据规模与约定

对于全部的测试点,保证 2≤n≤1052\le n\le 10^5,1≤m≤1051\le m\le 10^5,1≤a,b≤n1\le a,b\le n,c∈{0,1}c\in\{0,1\}。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 3;
#define ll long long
ll a[maxn],w[maxn * 4],lzy[maxn * 4];
void pushup(const int u) {
  w[u] = w[2 * u] + w[2 * u + 1];
}
bool InRange(int L,int R,int l,int r) {
  return (l <= L) && (R <= r);
}//判断是否完全包含
bool OutoRange(int L,int R,int l,int r) {
  return (R < l) || (L > r);
}//判断是否交集为空集
void maketag(int u,int len) {
  lzy[u] ^= 1;
  w[u] = len - w[u];
}//向下延迟修改
void pushdown(int u,int L,int R) {
  int mid = (L + R) / 2;
  maketag(2 * u,mid - L + 1);
  maketag(2 * u + 1,R - mid);
  lzy[u] = 0;
}//向下传递
ll query(int u,int L,int R,int l,int r) {
  if (InRange(L,R,l,r))
    return w[u];
  else if(!OutoRange(L,R,l,r)) {
    int mid = (L + R) / 2;
    pushdown(u,L,R);
    return query(2 * u,L,mid,l,r) + 
    query(2 * u + 1,mid + 1,R,l,r);
  }
  return 0;
}
void update(int u,int L,int R,int l,int r) {
  if (InRange(L,R,l,r)) 
    maketag(u,R - L + 1);
  else if (!OutoRange(L,R,l,r)) {
    int mid = (L + R) / 2;
    pushdown(u,L,R);
    update(2 * u,L,mid,l,r);
    update(2 * u + 1,mid + 1,R,l,r);
    pushup(u);
  }
}
int main() {
  int n,m;
  cin >> n >> m;
  memset(a,0,sizeof(a));
  for (int i = 1; i <= m; i++) {
    int op;
    cin >> op;
    if (op == 0) {
      int l,r;
      cin >> l >> r;
      update(1,1,n,l,r);
    }
    if (op == 1) {
      int l,r;
      cin >> l >> r;
      cout << query(1,1,n,l,r) << endl;
    }
  }
  return 0;
}
2024/8/27 20:02
加载中...