扫描线算法

Posted changer-qyz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了扫描线算法相关的知识,希望对你有一定的参考价值。

(昨天开训练赛,签到扫描线卡了三小时。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

 

以上是关于扫描线算法的主要内容,如果未能解决你的问题,请参考以下文章

扫描线算法的介绍与论证

扫描线算法

实现扫描线算法

多边形的扫描转换改进的X-扫描线算法

HDU 1542 Atlantis(扫描线算法)

扫描线填充算法