hdu1542 Atlantis
题意很简单就是给几个矩形的左下角坐标及右上角左边。求这几个矩形覆盖到的面积。
初学扫描线,太渣了各种不会,搜博客看到的都是粘贴别人的,无奈用了一个周六才完成。
这个题的思路大概是对纵坐标离散 建立线段树。依次插入排序后的竖边。iff为1则为入边,为0则为出边.面积等于每次插入时两个竖边距离与当前线段树中总长度的积之和。
我的渣渣代码:
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <vector>
#include <iostream>
#include <algorithm>
#define LL __int64
#define INF 0x3f3f3f3f
#define maxn 100005
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define Mid(a,b) (((a)+(b))/2)
using namespace std;
struct Node
{
int l,r;
int lnum,rnum,mnum;
int cover;
Node *pleft,*pright;
};
Node tree[maxn];
int Ncount;
void Build(Node *root,int l,int r)
{
root->cover=0;
root->l=l;
root->r=r;
root->mnum=root->lnum=root->rnum=r-l+1;
if(l==r)
return ;
Ncount++;
root->pleft=tree+Ncount;
Ncount++;
root->pright=tree+Ncount;
Build(root->pleft,l,(l+r)/2);
Build(root->pright,(l+r)/2+1,r);
}
int Ques(Node *root,int n)
{
if(root->l==root->r)
return root->l;
if(root->cover)//0 no operate
{
root->pright->cover=root->pleft->cover=root->cover;
if(root->cover==1)//1 be full
{
root->pright->lnum=root->pright->rnum=root->pright->mnum=0;
root->pleft->lnum=root->pleft->rnum=root->pleft->mnum=0;
}
else //be empty
{
root->pright->lnum=root->pright->rnum=root->pright->mnum=root->pright->r-root->pright->l+1;
root->pleft->lnum=root->pleft->rnum=root->pleft->mnum=root->pleft->r-root->pleft->l+1;
}
root->cover=0;
}
if(n<=root->pleft->mnum)
return Ques(root->pleft,n);
else if(n<=root->pleft->rnum+root->pright->lnum)
return Mid(root->l,root->r)-root->pleft->rnum+1;
else
return Ques(root->pright,n);
}
void Update(Node *root,int a,int b,int op)
{
if(a==root->l&&b==root->r)
{
root->cover=op;
if(op==1)
root->lnum=root->mnum=root->rnum=0;
else
root->lnum=root->mnum=root->rnum=root->r-root->l+1;
return ;
}
if(root->cover)
{
root->pright->cover=root->pleft->cover=root->cover;
if(root->cover==1)
{
root->pright->lnum=root->pright->rnum=root->pright->mnum=0;
root->pleft->lnum=root->pleft->rnum=root->pleft->mnum=0;
}
else
{
root->pright->lnum=root->pright->rnum=root->pright->mnum=root->pright->r-root->pright->l+1;
root->pleft->lnum=root->pleft->rnum=root->pleft->mnum=root->pleft->r-root->pleft->l+1;
}
root->cover=0;
}
if(b<=Mid(root->l,root->r))
Update(root->pleft,a,b,op);
else if(a>Mid(root->l,root->r))
Update(root->pright,a,b,op);
else
{
Update(root->pleft,a,Mid(root->l,root->r),op);
Update(root->pright,Mid(root->l,root->r)+1,b,op);
}
root->lnum=root->pleft->lnum;
root->rnum=root->pright->rnum;
if(root->lnum==root->pleft->r-root->pleft->l+1)
root->lnum+=root->pright->lnum;
if(root->rnum==root->pright->r-root->pright->l+1)
root->rnum+=root->pleft->rnum;
root->mnum=Max(root->pright->mnum,root->pleft->mnum);
root->mnum=Max(root->mnum,root->pleft->rnum+root->pright->lnum);
}
int main()
{
int n,q,a,b,s;
scanf("%d%d",&n,&q);
Ncount=0;
Build(tree,1,n);
while(q--)
{
scanf("%d",&s);
if(s==1)
{
scanf("%d",&a);
if(a<=tree->mnum)
{
int ans=Ques(tree,a);
Update(tree,ans,ans+a-1,1);
printf("%d\n",ans);
}
else
puts("0");
}
else
{
scanf("%d%d",&a,&b);
Update(tree,a,a+b-1,-1);
}
}
return 0;
}
hdu1828 Picture
求几个矩形的合并后的周长,直接用线段树记录已有竖边长度及线段个数。
周长等于每次插入竖边时总长变化差的绝对值之和+线段横坐标只差乘以线段个数之和。
很多需要注意的地方,如 是多组数据。。。
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <vector>
#include <iostream>
#include <algorithm>
#define LL __int64
#define INF 0x3f3f3f3f
#define maxn 105
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define Mid(a,b) (((a)+(b))/2)
#define lson root<<1,l,mid
#define rson root<<1|1,mid,r
using namespace std;
struct Node
{
int l,r,cover,len,num,ls,rs;
};
struct Line
{
int x,yu,yd;
int cover;
};
Node tree[60000];
Line line[60000];
int yy[60000];
int pla[60005];
bool cmp(Line a,Line b)
{
if(a.x==b.x)
return a.cover>b.cover;
else
return a.x<b.x;
}
void Build(int root , int l,int r)
{
tree[root].l=l;
tree[root].r=r;
tree[root].len=tree[root].cover=tree[root].num=tree[root].ls=tree[root].rs=0;
if(l+1==r)
return;
int mid=Mid(l,r);
Build(lson);
Build(rson);
}
void Push(int root)
{
if(tree[root].cover)
{
tree[root].len=yy[tree[root].r]-yy[tree[root].l];
tree[root].num=1;
tree[root].rs=tree[root].ls=1;
}
else if(tree[root].r-tree[root].l==1)
{
tree[root].len=0;
tree[root].num=0;
tree[root].rs=tree[root].ls=0;
}
else
{
tree[root].len=tree[root<<1].len+tree[root<<1|1].len;
tree[root].rs=tree[root<<1|1].rs;
tree[root].ls=tree[root<<1].ls;
tree[root].num=tree[root<<1].num+tree[root<<1|1].num;
if(tree[root<<1].rs&&tree[root<<1|1].ls)
tree[root].num-=1;
}
}
void Update(int root,int l,int r,int cover)
{
if(r<tree[root].l||l>tree[root].r)
return ;
if(l<=tree[root].l&&r>=tree[root].r)
{
tree[root].cover+=cover;
Push(root);
return ;
}
Update(root<<1,l,r,cover);
Update(root<<1|1,l,r,cover);
Push(root);
}
int main()
{
int n;
while(scanf("%d",&n)==1)
{
if(n==0)
{
printf("0\n");
continue;
}
int con=0;
int x1,x2,y1,y2;
for(int i=1; i<=n; i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
line[con].yu=y2;
line[con].yd=y1;
line[con].x=x1;
line[con].cover=1;
yy[con++]=y1;
line[con].yu=y2;
line[con].yd=y1;
line[con].x=x2;
line[con].cover=-1;
yy[con++]=y2;
}
stable_sort(line,line+con,cmp);
stable_sort(yy,yy+con);
int num=unique(yy,yy+con)-yy;
for(int i=0; i<num; i++)
pla[yy[i]+20000]=i;
Build(1,0,num-1);
int lastl=0;
long long res=0;
for(int i=0; i<con; i++)
{
int foo=1;
if(tree[1].len) res+=(line[i].x-line[i-1].x)*tree[1].num*2;
Update(1,pla[line[i].yd+20000],pla[line[i].yu+20000],line[i].cover);
while(line[i+1].x==line[i].x)
{
if(foo&&line[i+1].cover==line[i].cover)
{
Update(1,pla[line[i+1].yd+20000],pla[line[i+1].yu+20000],line[i+1].cover);
i++;
}
else if(foo&&line[i+1].cover!=line[i].cover)
{
foo=0;
res+=abs(lastl-tree[1].len);
lastl=tree[1].len;
Update(1,pla[line[i+1].yd+20000],pla[line[i+1].yu+20000],line[i+1].cover);
i++;
}
else
{
Update(1,pla[line[i+1].yd+20000],pla[line[i+1].yu+20000],line[i+1].cover);
i++;
}
}
res+=abs(lastl-tree[1].len);
lastl=tree[1].len;
}
res+=abs(lastl);
printf("%lld\n",res);
}
return 0;
}