题解:贪婪大陆

洛谷P2184

Posted by TH911 on December 14, 2024

题目传送门

树状数组

我们开两个权值树状数组 $tl,tr$,分别存储布雷的左、右边界。

那么对于给定区间 $[l,r]$,答案即 $tl.query(r)-tr.query(l-1)$。

如图:

蓝色即布雷区间,黑色即查询区间。

$\color{black}\colorbox{black}{1}$ 黑色右区间之前的 $\color{skyblue}\colorbox{skyblue}{1}$ 蓝色左边界所在区间才有可能与 $\color{black}\colorbox{black}{1}$ 黑色区间重合。

那么我们再减去 $\color{black}\colorbox{black}{1}$ 黑色区间左边界左边的 $\color{skyblue}\colorbox{skyblue}{1}$ 蓝色左边界数量(未重合)即可。

AC 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<ctime>
#include<deque>
#include<queue>
#include<stack>
#include<list>
using namespace std;
constexpr const int N=1e5;
struct tree{
	int t[N+1];
	
	int lowbit(int x){
		return x&-x;
	}
	void add(int x,int k){
		while(x<=N){
			t[x]+=k;
			x+=lowbit(x);
		}
	}
	int query(int x){
		int ans=0;
		while(x){
			ans+=t[x];
			x-=lowbit(x);
		}return ans;
	}
}tl,tr;
int n,m;
int main(){
	/*freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);*/
	
	scanf("%d %d",&n,&m);
	while(m--){
		int q,l,r;
		scanf("%d %d %d",&q,&l,&r);
		switch(q){
			case 1:
				tl.add(l,1);tr.add(r,1);
				break;
			case 2:
				printf("%d\n",tl.query(r)-tr.query(l-1));
				break;
		}
	}
	
	/*fclose(stdin);
	fclose(stdout);*/
	return 0;
}