题意:
给出一个左下角为
(
0
,
0
)
(0,0)
(0,0),右上角为
(
n
,
m
)
(n,m)
(n,m)的矩形,然后给你
k
k
k条射线,每条射线的起点及方向(上下左右)都已知,射线的起点都位于矩形内,不包括矩形边界,且每条射线间不会有重叠,求矩形被分割成多少块。
思路:
用线段树解,题中说是射线,所以我们可以对y轴离散化,对x轴排序后用线段树维护y轴坐标,遇到向上或向下的射线,则在线段树区间上加一,当遇见向左的射线时,对y轴进行单点查询然后ans加上这个结果。然后从右到左再处理一遍,与上面相同。
#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int N = 2e5 + 1000;
struct node {
ll sum[N << 2], add[N << 2];
void init() {
memset(sum, 0, sizeof sum);
memset(add, 0, sizeof add);
}
void pushup(int rt) {
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void PushDown(int rt, int ln, int rn) {
if(add[rt]) {
add[rt << 1] += add[rt];
add[rt << 1 | 1] += add[rt];
sum[rt << 1] += add[rt] * ln;
sum[rt << 1 | 1] += add[rt] * rn;
add[rt] = 0;
}
}
void Update(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
sum[rt] += (r - l + 1);
add[rt] += 1;
return;
}
int m = (l + r) >> 1;
PushDown(rt, m - l + 1, r - m);
if(L <= m)
Update(L, R, l, m, rt << 1);
if(R > m)
Update(L, R, m + 1, r, rt << 1 | 1);
pushup(rt);
}
ll query(int x, int l, int r, int rt) {
if(l == r) {
return sum[rt];
}
int m = (r + l) >> 1;
PushDown(rt, m - l + 1, r - m);
if(x <= m)
return query(x, l, m, rt << 1);
else
return query(x, m + 1, r, rt << 1 | 1);
}
} tree;
int t, n, m, k;
struct nod {
int x, y;
char c;
bool operator <(const nod &a)const {
return x < a.x;
}
} no[N];
vector<int> v;
int getid(int x) {
return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d%d%d", &n, &m, &k);
tree.init(), v.clear();
for(int i = 1; i <= k; i++) {
scanf("%d%d %c", &no[i].x, &no[i].y, &no[i].c);
v.push_back(no[i].y);
}
sort(no + 1, no + k + 1);
sort(v.begin(), v.end());
ll ans = 1;
for(int i = 1; i <= k; i++) {
int id = getid(no[i].y);
if(no[i].c == 'U')
tree.Update(id, k, 1, k, 1);
else if(no[i].c == 'D')
tree.Update(1, id, 1, k, 1);
else if(no[i].c == 'L')
ans += tree.query(id, 1, k, 1);
}
tree.init();
for(int i = k; i > 0; i--) {
int id = getid(no[i].y);
if(no[i].c == 'U')
tree.Update(id, k, 1, k, 1);
else if(no[i].c == 'D')
tree.Update(1, id, 1, k, 1);
else if(no[i].c == 'R')
ans += tree.query(id, 1, k, 1);
}
printf("%lld\n", ans);
}
return 0;
}