链接:https://ac.nowcoder.com/acm/contest/1108/H
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
Special Judge, 64bit IO Format: %lld
题目描述
Bobo 精通数据结构!他想维护一个线段的集合 S。初始时,S 为空。他会依次进行 q 次操作,操作有 2 种。
* 类型 1:给出 l, r,向集合 S 中插入线段 [l, r].
* 类型 2:给出 l, r,询问满足 [x,y]∈S[x, y] \in S[x,y]∈S 且 x≤l≤r≤yx \leq l \leq r \leq yx≤l≤r≤y 的线段 [x, y] 数量。
帮 Bobo 求出每次询问的答案。
输入描述:
输入文件包含多组数据,请处理到文件结束。 每组数据的第一行包含 2 个整数 n 和 q. 其中 n 表示操作中 r 的最大值。 接下来 q 行中的第 i 行包含 3 个整数 ti,li,rit_i, l_i, r_iti,li,ri,表示第 i 个操作属于类型 tit_iti,对应的参数是 lil_ili 和 rir_iri.
输出描述:
对于每个类型 2 的询问,输出 1 个整数表示对应的数量。
示例1
输入
复制
1 2 1 1 1 2 1 1 4 4 1 1 4 2 2 3 1 1 4 2 2 3
输出
复制
1 1 2
备注:
* 1≤n,q≤1051 \leq n, q \leq 10^51≤n,q≤105 * ti∈{1,2}t_i \in \{1, 2\}ti∈{1,2} * 1≤li≤ri≤n1 \leq l_i \leq r_i \leq n1≤li≤ri≤n * 对于 ti=2t_i = 2ti=2 的操作,ri−li≤2r_i - l_i \leq 2ri−li≤2 成立。 * 数据组数不超过 10.
这道题最重要的是操作2的时候ri-li<=2这个条件。我们这样想,在对于一个操作1的时候,放入l,r。这个线段l,r能够产生作用的范围是有限的:他会对结尾为l+2到r的,长度为3的操作2线段查询产生一次贡献。会对结尾为l+1到r的,长度为2的操作2的线段查询产生一次贡献.会对结尾为l到r的,长度为1的操作2的线段查询产生一次贡献。这样我们建立三个树分别维护这个信息就好了。
#include<bits/stdc++.h>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline bool sc(int &num){
char in; bool IsN = false;
in = getchar();
if (in == EOF) return false;
while (in != '-' && (in<'0' || in>'9')) in = getchar();
if (in == '-') { IsN = true; num = 0; }
else num = in - '0';
while (in = getchar(), in >= '0'&&in <= '9') {
num *= 10, num += in - '0';
}
if (IsN) num = -num;
return true;
}
const int M = 100010;
int lazy[M * 6][3];
void pushdown(int rt,int kind) {
if (lazy[rt][kind]) {
lazy[rt << 1][kind] += lazy[rt][kind];
lazy[rt << 1 | 1][kind] += lazy[rt][kind];
lazy[rt][kind] = 0;
}
}
void build(int l, int r, int rt) {
lazy[rt][0] = lazy[rt][1] = lazy[rt][2] = 0;
if (l == r) {
return;
}
int mid = (l + r) >> 1;
build(lson); build(rson);
}
void update(int l, int r, int rt, int L,int R,int kind) {
if (L <= l && r <= R) {
lazy[rt][kind] += 1;
return;
}
pushdown(rt, kind);
int mid = (l + r) >> 1;
if (L <= mid) {
update(lson, L, R, kind);
}
if (R > mid) {
update(rson, L, R, kind);
}
return;
}
int query(int l, int r, int rt, int x,int kind) {
if (l == r) {
return lazy[rt][kind];
}
int mid = (l + r) >> 1;
pushdown(rt, kind);
if (x <= mid)return query(lson, x, kind);
else return query(rson, x, kind);
}
int main() {
int n, m;
while (~scanf("%d%d",&n,&m)) {
build(1, n, 1);
while (m--) {
int a, b, c;
sc(a); sc(b); sc(c);
if (a == 1) {
int len = c - b + 1;
if (len == 1) {
update(1, n, 1, b, b, 0);
}
else if (len == 2) {
update(1, n, 1, b, c, 0);
update(1, n, 1, c, c, 1);
}
else {
update(1, n, 1, b, c, 0);
update(1, n, 1, b + 1, c, 1);
update(1, n, 1, b + 2, c, 2);
}
}
else {
printf("%d\n", query(1, n, 1, c, c - b));
}
}
}
return 0;
}