二维数点

给定$n$个坐标$(x,y)$,再给$q$个询问求矩形内点的个数

非CDQ(离线)

所以只要统计
$Sum(0,0,x,y)$
可以确定好$x$后查询区间的$y$范围的个数用树状数组维护即可。坐标过大离散化即可。

加修改

CDQ(离线)

转换为三维偏序,CDQ算贡献时注意下对询问和修改的分类就好了

树套树

树状数组维护前缀和的权值线段树

待修改
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define lowbit(i) i &(-i)
const int N = 5e5 + 10;
int tr[N];
int cnt, n;
void update(int x, int w)
{
while (x <= n)
{
tr[x] += w;
x += lowbit(x);
}
return;
}
int quary(int x)
{
int sum = 0;
while (x)
{
sum += tr[x];
x -= lowbit(x);
}
return sum;
}
int ans[N];
struct node
{
int x, y, w, op, flag, id;
} q[N * 4];
bool cmpx(node a, node b)
{
return a.x == b.x ? a.y < b.y : a.x < b.x;
}
void add(int x, int y, int flag, int id)
{
q[++cnt].x = x;
q[cnt].y = y;
q[cnt].flag = flag;
q[cnt].op = 2;
q[cnt].id = id;
}
void cdq(int l, int r)
{
if (l == r)
return;
int mid = (l + r) >> 1;
cdq(l, mid);
cdq(mid + 1, r);
sort(q + l, q + 1 + mid, cmpx);
sort(q + 1 + mid, q + 1 + r, cmpx);
int pl = l, pr = mid + 1;
while (pr <= r)
{
//cout<<pl<<" "<<pr<<endl;
while (q[pl].op == 2 && pl <= mid)
pl++;
while (q[pr].op == 1 && pr <= r)
pr++;

if (pl <= mid && q[pl].x <= q[pr].x)
update(q[pl].y, q[pl].w),pl++;
else if (pr <= r)
ans[q[pr].id] += q[pr].flag * quary(q[pr].y),pr++;
}
for (int i = l; i < pl; i++)
if(q[i].op==1)
update(q[i].y, -q[i].w);
}
int ask;
int main()
{
scanf("%d", &n);
while (1)
{
int p;
scanf("%d", &p);
if (p == 1)
{
++cnt;
scanf("%d%d%d", &q[cnt].x, &q[cnt].y, &q[cnt].w);
q[cnt].op = p;
}
else if (p == 2)
{
ask++;

int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);

add(x2, y2, 1, ask);
add(x1 - 1, y1 - 1, 1, ask);
add(x2, y1 - 1, -1, ask);
add(x1 - 1, y2, -1, ask);
}
else
break;
}
//cout<<cnt<<endl;
cdq(1,cnt);
//cout<<ask<<endl;
for(int i=1;i<=ask;i++)
printf("%d\n",ans[i]);
}