HDU1828 Picture
-———————————
扫描线求周长
链接(HDU):Miku
链接(Vjudge):Miku
-———————————
HDU是多组数据!!!而且不写明白了!!!
我本以为既然多组数据,何不写上一共几组,既然不写,那必然是不存在了
但是它就是多组数据
-——————————-
这道题显然的做法是扫描两次,横着一次竖着一次,不过会很繁琐
事实上,一次就够了
-———————————
完全可以从上向下扫描一次,对于竖线,显然就是两条线段之间的高度*区间个数*2(更新前)
而对于横线,就是两次的区间长度之差的绝对值(因为无论是+还是-,裸露出来的就是变化的长度)
-————————————
这样就变成了两个小问题了
横线的求法,没有特别之处,但是竖线,因为是求区间线段数,就要特别处理一下了
我用了额外两个数组,ld,rd,代表一个区间的左右端点是否被覆盖,显然左端点就是左儿子左端点,右端点同理
但是如果左右儿子连起来了,还要特判
所以pushup更长了
void pushup(int x,int l,int r){
if(lazy[x]>=1){
sum[x]=r-l+1;
summ[x]=2;
ld[x]=rd[x]=1;
}
else if(l!=r){
sum[x]=sum[x<<1]+sum[x<<1|1];
ld[x]=ld[x<<1];
rd[x]=rd[x<<1|1];
summ[x]=summ[x<<1]+summ[x<<1|1];
if(ld[x<<1|1]&&rd[x<<1]) summ[x]-=2;
}
else{
sum[x]=0;
summ[x]=0;
ld[x]=0;
rd[x]=0;
}
}
-—————————————
这样来看,整个代码也就呼之欲出了
-——————————————
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int xx,yy,xxx,yyy;
long long ans;
const int maxn=100000;
int last;
struct li{
int l;
int r;
long long h;
int f;
}line[200005];
int n;
int p;
int sum[4000005];
bool ld[4000005],rd[4000005];
int lazy[4000005];
int summ[4000005];
int lm;
int rm;
bool cmp(li x,li y){
return x.h<y.h;
}
void pushup(int x,int l,int r){
if(lazy[x]>=1){
sum[x]=r-l+1;
summ[x]=2;
ld[x]=rd[x]=1;
}
else if(l!=r){
sum[x]=sum[x<<1]+sum[x<<1|1];
ld[x]=ld[x<<1];
rd[x]=rd[x<<1|1];
summ[x]=summ[x<<1]+summ[x<<1|1];
if(ld[x<<1|1]&&rd[x<<1]) summ[x]-=2;
}
else{
sum[x]=0;
summ[x]=0;
ld[x]=0;
rd[x]=0;
}
}
void update(int x,int l,int r,int L,int R,int d){
if(L<=l&&r<=R){
lazy[x]+=d;
pushup(x,l,r);
return ;
}
int mid=(l+r)>>1;
if(L<=mid) update(x<<1,l,mid,L,R,d);
if(R>mid) update(x<<1|1,mid+1,r,L,R,d);
pushup(x,l,r);
}
int main(){
while(~scanf("%d",&n)){
cin>>n;
p=0;
ans=0;
last=0;
lm=-10000;
rm=10000;
for(int i=1;i<=n;++i){
scanf("%d%d%d%d",&xx,&yy,&xxx,&yyy);
lm=min(lm,xx);
rm=max(rm,xxx);
p++;
line[p].l=xx;
line[p].r=xxx;
line[p].h=yy;
line[p].f=1;
p++;
line[p].l=xx;
line[p].r=xxx;
line[p].h=yyy;
line[p].f=-1;
}
sort(line+1,line+p+1,cmp);
for(int i=1;i<=p;++i){
update(1,lm,rm-1,line[i].l,line[i].r-1,line[i].f);
ans+=summ[1]*(line[i+1].h-line[i].h);
ans+=abs(sum[1]-last);
last=sum[1];
}
cout<<ans;
}
return 0;
}
不知道为啥,这份代码从左往右扫会有BUG
还没有评论,来说两句吧...