题意:给一个矩形,在矩形内部有很多射线,这些射线的起点不会碰到矩形边界,问这些射线把矩形分成了几部分
题解:分成的区域数等于线段交点数加一,推导还是看jls的题解把
单说求交点个数的问题,我的方法就是扫描线+线段树/树状数组,但是树状数组不太了解,那就用树状数组做吧!
1e9的数据肯定先离散化
我把横线(平行于x轴的)当做枚举的对象,那些竖线(平行于y轴的)就记录他们的头尾,然后头设置值为1,尾设置值为-1,把横线记录左边的x右边的x和高度y,然后按y排序,扫描线扫到第一条横线的时候,把所有高度小于等于这条横线的竖线的起始点和结尾点都用树状数组单点更新,更新完毕就用树状数组查询横线包含的区间内所有值的和,就是这条线的交点个数
注意一下不是记录竖线结尾点设置为-1,而是记录比竖线结尾y值大1的点为-1,为了表示射线无线延长的特点,我在离散的时候还加入了0作为最小值,和max(m,n)作为最大值
#include <iostream>
#include <stdio.h>
#include <queue>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include <math.h>
#include <time.h>
#include <algorithm>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const ll mod=998244353;
const int maxn=1e6+100;
int n,m,k;
int sum[maxn];
struct Line
{
int xl,xr,y;
Line(){}
Line(int xl,int xr,int y):xl(xl),xr(xr),y(y){}
};
struct PO
{
int x,y,f;
PO(){}
PO(int x,int y,int f):x(x),y(y),f(f){}
};
struct nn
{
int x,y;
char a[2];
}o[maxn];
vector<Line>H;
vector<PO>S;
vector<int>ls;
int cmpPO(PO a,PO b)
{
return a.y<b.y;
}
int cmpL(Line a,Line b)
{
return a.y<b.y;
}
void update(int i,int tot,int c)
{
for(;i<tot;i+=i&(-i))sum[i]+=c;
}
int query(int i)
{
int res=0;
for(;i>0;i-=i&(-i))res+=sum[i];
return res;
}
int main() {
// freopen("in1.txt","r",stdin);
// freopen("out.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--){
H.clear();
S.clear();
ls.clear();
memset(sum,0,sizeof sum);
scanf("%d%d%d",&n,&m,&k);
ls.push_back(max(n,m));
ls.push_back(0);
for(int i=1;i<=k;i++){
scanf("%d%d%s",&o[i].x,&o[i].y,o[i].a);
ls.push_back(o[i].x);
ls.push_back(o[i].y);
}
sort(ls.begin(),ls.end());
int tot=unique(ls.begin(),ls.end())-ls.begin();
for(int i=1;i<=k;i++){
int x=lower_bound(ls.begin(),ls.begin()+tot,o[i].x)-ls.begin();
int y=lower_bound(ls.begin(),ls.begin()+tot,o[i].y)-ls.begin();
if(o[i].a[0]=='U'){
S.push_back(PO(x,y,1));
S.push_back(PO(x,tot-1,-1));
}
else if(o[i].a[0]=='D'){
S.push_back(PO(x,1,1));
S.push_back(PO(x,y+1,-1));
}
else if(o[i].a[0]=='L'){
H.push_back(Line(1,x,y));
}
else if(o[i].a[0]=='R'){
H.push_back(Line(x,tot-1,y));
}
}
sort(H.begin(),H.end(),cmpL);
sort(S.begin(),S.end(),cmpPO);
int ans=1,posP=0;
for(int i=0;i<H.size();i++){
while(posP<S.size() && S[posP].y<=H[i].y){
update(S[posP].x,tot,S[posP].f);
posP++;
}
ans+=query(H[i].xr)-query(H[i].xl-1);
}
printf("%d\n",ans);
}
}