HDU 6681 Rikka with Cake(扫描线、动态开点线段树)

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 }

 

你可能感兴趣的:(HDU 6681 Rikka with Cake(扫描线、动态开点线段树))