CSU - 2170 千萬別用樹套樹(線段樹)

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章