http://acm.hdu.edu.cn/showproblem.php?pid=6681
题意
在矩形区域内有k条射线,问这些射线将矩形分成了多少区域
题解
容易发现答案为所有射线交点个数+1。
按y从排序扫描矩形区域,动态开点线段树维护区间内竖线的个数,由于n,m范围较大,需要离散化处理,但这样比较麻烦且此题空间足够所以建议用动态开点。
1 #define bug(x) cout<<#x<<" is "<endl 2 #define IO std::ios::sync_with_stdio(0) 3 #include 4 #define iter ::iterator 5 #define pa pair<int,ll> 6 using namespace std; 7 #define ll long long 8 #define mk make_pair 9 #define pb push_back 10 #define se second 11 #define fi first 12 ll mod=998244353; 13 const int N=1e5+5; 14 int T; 15 struct node{ 16 int x1,x2,y,z; 17 bool operator <(const node &t)const{ 18 if(y==t.y)return z<t.z; 19 return y<t.y; 20 } 21 }a[N]; 22 int cnt; 23 int sum[N*32],ls[N*32],rs[N*32]; 24 void up(int &o,int l,int r,int p,int v){ 25 if(!o)o=++cnt; 26 sum[o]+=v; 27 if(l==r)return; 28 int m=(l+r)/2; 29 if(p<=m)up(ls[o],l,m,p,v); 30 else up(rs[o],m+1,r,p,v); 31 } 32 int qu(int o,int l,int r,int ql,int qr){ 33 if(l>=ql&&r<=qr){ 34 return sum[o]; 35 } 36 int res=0; 37 int m=(l+r)/2; 38 if(ql<=m)res+=qu(ls[o],l,m,ql,qr); 39 if(qr>m)res+=qu(rs[o],m+1,r,ql,qr); 40 return res; 41 } 42 43 int main(){ 44 scanf("%d",&T); 45 while(T--){ 46 int n,m,k; 47 scanf("%d%d%d",&n,&m,&k); 48 int rt=0; 49 cnt=0; 50 for(int i=1;i<=k;i++){ 51 int x,y; 52 char s[10]; 53 scanf("%d%d%s",&x,&y,s); 54 char op=s[0]; 55 a[i].x1=a[i].x2=x; 56 a[i].y=y; 57 if(op=='U')a[i].z=1; 58 else if(op=='L'){ 59 a[i].z=2; 60 a[i].x1=1; 61 } 62 else if(op=='R'){ 63 a[i].z=2; 64 a[i].x2=n; 65 } 66 else{ 67 a[i].z=3; 68 up(rt,1,n,a[i].x1,1); 69 } 70 } 71 sort(a+1,a+1+k); 72 ll ans=1; 73 for(int i=1;i<=k;i++){ 74 if(a[i].z==1)up(rt,1,n,a[i].x1,1); 75 else if(a[i].z==2){ 76 ans+=qu(rt,1,n,a[i].x1,a[i].x2); 77 } 78 else up(rt,1,n,a[i].x1,-1); 79 } 80 printf("%lld\n",ans); 81 for(int i=1;i<=cnt;i++) 82 sum[i]=ls[i]=rs[i]=0; 83 } 84 }