题意:给你一个n*m的的矩形框 现在又k条射线 问这个矩形框会被分为多少个区域
思路:之前的想法是枚举边界然后线段树扫一遍计算一下矩形个数 复杂度果断不行 后面发现其实答案就是交点数+1 然后就用线段树上下扫两边
#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const int N = 1e5+7;
const int inf = 0x3f3f3f3f;
typedef long long ll;
const ll mod = 1e7+9;
struct tree{
int l,r,v;
};
tree t[N<<2];
struct node{
int x,y,z;
}up[N],down[N];
int xx[N];
bool cmp1(node a,node b){
return a.y<b.y; //升
}
bool cmp2(node a,node b){
return a.y>b.y; //降
}
void build(int p,int l,int r){
t[p].l=l; t[p].r=r; t[p].v=0;
if(l==r){
return ;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
t[p].v=t[p<<1].v+t[p<<1|1].v;
}
void update(int p,int x,int v){
if(t[p].l==t[p].r&&t[p].l==x){
t[p].v+=v;
return ;
}
int mid=(t[p].l+t[p].r)>>1;
if(x<=mid) update(p<<1,x,v);
else update(p<<1|1,x,v);
t[p].v=t[p<<1].v+t[p<<1|1].v;
}
ll query(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r){
return t[p].v;
}
int mid=(t[p].l+t[p].r)>>1;
ll res=0;
if(l<=mid) res+=query(p<<1,l,r);
if(r>mid) res+=query(p<<1|1,l,r);
return res;
}
int getpo(int x,int n){
int po=lower_bound(xx,xx+n,x)-xx+1;
return po;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int t; cin>>t;
while(t--){
int n,m,k; cin>>n>>m>>k;
int cnt=0; int cntup=0; int cntdown=0;
xx[cnt++]=1; xx[cnt++]=n-1;
for(int i=1;i<=k;i++){
int x,y; char ty;
cin>>x>>y>>ty;
xx[cnt++]=x;
if(ty=='U'){
up[cntup++]=node{x,y,1};
}else if(ty=='D'){
down[cntdown++]=node{x,y,1};
}else if(ty=='L'){
up[cntup++]=node{x,y,0};
down[cntdown++]=node{x,y,0};
}else{
up[cntup++]=node{x,y,3};
down[cntdown++]=node{x,y,3};
}
}
sort(xx,xx+cnt);
cnt=unique(xx,xx+cnt)-xx;
sort(up,up+cntup,cmp1);
sort(down,down+cntdown,cmp2);
build(1,1,cnt);
ll ans=1;
for(int i=0;i<cntup;i++){
if(up[i].z==1){
int po=getpo(up[i].x,cnt);
update(1,po,1);
}else if(up[i].z==0){
int l=getpo(1,cnt); int r=getpo(up[i].x,cnt);
ans+=query(1,l,r);
}else{
int l=getpo(up[i].x,cnt); int r=getpo(n-1,cnt);
ans+=query(1,l,r);
}
}
build(1,1,cnt);
for(int i=0;i<cntdown;i++){
if(down[i].z==1){
int po=getpo(down[i].x,cnt);
update(1,po,1);
}else if(down[i].z==0){
int l=getpo(1,cnt); int r=getpo(down[i].x,cnt);
ans+=query(1,l,r);
}else{
int l=getpo(down[i].x,cnt); int r=getpo(n-1,cnt);
ans+=query(1,l,r);
}
}
cout<<ans<<endl;
}
}