扫描线算法

(昨天开训练赛,签到扫描线卡了三小时。wsl。

1. 矩形周长并

hdoj1828 / poj1177

传送:http://acm.hdu.edu.cn/showproblem.php?pid=1828

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=1e4+10;
 6 struct node{
 7     int h,l,r,val;
 8 }e[maxn];
 9 int refl[maxn];
10 struct node2{
11     int l,r,len,ysum;
12     int cnt;
13     bool lv,rv;
14 }tree[maxn<<1];
15 bool cmp(node p,node q){
16     return (p.h!=q.h)?(p.h<q.h):(p.val>q.val);
17 }
18 void build(int root,int l,int r){
19     tree[root].l=l;tree[root].r=r;
20     tree[root].cnt=0;tree[root].len=0;tree[root].ysum=0;
21     tree[root].lv=false;tree[root].rv=false;
22     if (l==r) return ;
23     int mid=(l+r)>>1;
24     build(root<<1,l,mid);
25     build(root<<1|1,mid+1,r);
26 }
27 void pushdown(int root){
28     if (tree[root].cnt){
29         tree[root].len=refl[tree[root].r+1]-refl[tree[root].l];
30         tree[root].lv=true; tree[root].rv=true;
31         tree[root].ysum=1;
32     }
33     else if (tree[root].l==tree[root].r){
34         tree[root].lv=false; tree[root].rv=false;
35         tree[root].len=0; tree[root].ysum=0;
36     }
37     else{
38         tree[root].len=tree[root<<1].len+tree[root<<1|1].len;
39         tree[root].lv=tree[root<<1].lv;
40         tree[root].rv=tree[root<<1|1].rv;
41         tree[root].ysum=tree[root<<1].ysum+tree[root<<1|1].ysum-tree[root<<1|1].lv*tree[root<<1].rv;
42     }
43 } 
44 void update(int root,int xx,int yy,int kk){
45     if (xx<=tree[root].l && yy>=tree[root].r){
46         tree[root].cnt+=kk;
47         pushdown(root);
48         return ;
49     }
50     int mid=(tree[root].l+tree[root].r)>>1;
51     if (yy<=mid) update(root<<1,xx,yy,kk);
52     else if (xx>mid) update(root<<1|1,xx,yy,kk);
53     else{
54         update(root<<1,xx,mid,kk);
55         update(root<<1|1,mid+1,yy,kk);
56     }
57     pushdown(root);
58 }
59 int main(){
60     int n,x,y,xx,yy;
61     while (~scanf("%d",&n)){
62         int num=0;
63         for (int i=1;i<=n;i++){
64             scanf("%d%d%d%d",&x,&y,&xx,&yy);
65             e[++num]={y,x,xx,1}; refl[num]=x;
66             e[++num]={yy,x,xx,-1}; refl[num]=xx;
67         }
68         sort(refl+1,refl+1+num);
69         sort(e+1,e+1+num,cmp);
70         int tot=unique(refl+1,refl+1+num)-(refl+1);
71         build(1,1,tot);
72         int ans=0,lastlen=0;
73         for (int i=1;i<=num;i++){
74             int ll=lower_bound(refl+1,refl+1+tot,e[i].l)-refl;
75             int rr=lower_bound(refl+1,refl+1+tot,e[i].r)-refl-1;
76             update(1,ll,rr,e[i].val);
77             ans+=2*tree[1].ysum*(e[i+1].h-e[i].h);
78             ans+=abs(tree[1].len-lastlen);
79             lastlen=tree[1].len;
80         }
81         printf("%d\n",ans);
82     }
83     return 0;
84 } 
hdoj1828

 

posted @ 2019-10-04 15:56  Changer-qyz  阅读(...)  评论(...编辑  收藏