题意:
给你
k
k
k 条平行于x轴或y轴的射线, 问这些射线把封闭区域
n
∗
m
n*m
n∗m的矩形分成了几个封闭部分。
思路:
因为射线都是平行于坐标轴的,那么考虑线段树维护。
离散化坐标后,按照
x
x
x坐标从小到大排序。
第一遍:如果当前点是竖着分割,那么分割的区间值加一,表示当前这段区间
y
y
y坐标都有射线经过。 如果当前点是横着分割的,那么直接单点查询当前点
y
y
y坐标的值。
(debug半天,发现pushdown写错了sdajlskfdjas)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
typedef long long ll;
struct node{
int x,y;
char dir[2];
}p[maxn<<2];
bool cmp(node a,node b){
return a.x < b.x;
}
vector<int>idx,idy;
ll sum[maxn<<2],add[maxn<<2];
void pushup(int rt){
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void pushdown(int rt,int len){
if(add[rt]){
add[rt<<1] += add[rt];
add[rt<<1|1] += add[rt];
sum[rt<<1] += 1LL*add[rt]*(len-(len>>1));
sum[rt<<1|1] += 1LL*add[rt]*((len>>1));
add[rt] = 0;
}
}
void build(int l,int r,int rt){
sum[rt] = add[rt] = 0;
if(l == r){
return ;
}
int mid = l+r>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
}
void update(int l,int r,int rt,int L,int R,ll val){
if(L <= l && R >= r){
sum[rt] += 1LL*(r-l+1)*val;
add[rt] += val;
return;
}
pushdown(rt,r-l+1);
int mid = (l+r)>>1;
if(L <= mid) update(l,mid,rt<<1,L,R,val);
if(R > mid) update(mid+1,r,rt<<1|1,L,R,val);
pushup(rt);
}
ll query(int l,int r,int rt, int pos){
if(l == r){
return sum[rt];
}
pushdown(rt,r-l+1);
int mid = (l+r)>>1;
if(pos <= mid) return query(l,mid,rt<<1,pos);
else return query(mid+1,r,rt<<1|1,pos);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
idx.clear(), idy.clear();
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i = 1; i <= k; i++){
scanf("%d%d%s",&p[i].x,&p[i].y,p[i].dir);
idx.push_back(p[i].x);
idy.push_back(p[i].y);
}
sort(idx.begin(), idx.end());
idx.erase(unique(idx.begin(), idx.end()), idx.end());
sort(idy.begin(), idy.end());
idy.erase(unique(idy.begin(), idy.end()), idy.end());
for(int i = 1; i <= k; i++){
p[i].x = lower_bound(idx.begin(), idx.end(), p[i].x) - idx.begin() + 1;
p[i].y = lower_bound(idy.begin(), idy.end(), p[i].y) - idy.begin() + 1;
}
sort(p+1,p+k+1,cmp);
ll ans = 0;
build(1,100001,1);
for(int i = 1; i <= k; i++){
if(p[i].dir[0] == 'U') update(1,100001,1,p[i].y,100000,1ll);
if(p[i].dir[0] == 'D') update(1,100001,1,1,p[i].y,1ll);
if(p[i].dir[0] == 'L') ans += query(1,100001,1,p[i].y);
//printf("sum[1],%lld\n",sum[1]);
//if(p[i].dir[0] == 'R') ans += query(1,100000,1,p[i].y);
}
build(1,100001,1);
for(int i = k; i >= 1; i--){
if(p[i].dir[0] == 'U') update(1,100001,1,p[i].y,100000,1ll);
if(p[i].dir[0] == 'D') update(1,100001,1,1,p[i].y,1ll);
if(p[i].dir[0] == 'R') ans += query(1,100001,1,p[i].y);
//if(p[i].dir[0] == 'R') ans += query(1,100000,1,p[i].y);
}
printf("%lld\n",ans+1);
}
return 0;
}