鏈接: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;
}