用魔改线段树练一练手
毕竟刚学会,还不太熟
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
struct line
{
double x,y1,y2;
int fla;
} p[maxn];
bool cmp(line a,line b)
{
return a.x<b.x;
}
double v[maxn];
struct node
{
double l,r,len;
int lazy;
} tr[maxn<<3];
void build(int k,int l,int r)
{
tr[k].lazy=tr[k].len=0;
tr[k].l=v[l],tr[k].r=v[r];
if(r-l<=1)
return;
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid,r);
}
void pushup(int k)
{
if(tr[k].lazy)
tr[k].len=tr[k].r-tr[k].l;
else
tr[k].len=tr[k<<1].len+tr[k<<1|1].len;
}
void modify(int k,double l,double r,int w)
{
if(tr[k].l>=l&&tr[k].r<=r)
{
tr[k].lazy+=w;
pushup(k);
return ;
}
if(tr[k<<1].r>l)
{
modify(k<<1,l,r,w);
}
if(tr[k<<1|1].l<r)
{
modify(k<<1|1,l,r,w);
}
pushup(k);
}
int main()
{
ios::sync_with_stdio(false);
int n,id=0;
while(cin>>n&&n)
{
int t=0;
double x1,x2,y1,y2;
for(int i=1; i<=n; i++)
{
cin>>x1>>y1>>x2>>y2;
p[i*2-1]=(line)
{
x1,y1,y2,1
};
p[i*2]=(line)
{
x2,y1,y2,-1
};
v[++t]=y1,v[++t]=y2;
}
cout<<"Test case #"<<++id<<endl;
sort(v+1,v+1+t);
sort(p+1,p+1+t,cmp);
build(1,1,t);
double ans=0;
for(int i=1; i<t; i++)
{
modify(1,p[i].y1,p[i].y2,p[i].fla);
ans+=(p[i+1].x-p[i].x)*tr[1].len;
}
cout<<"Total explored area: "<<fixed<<setprecision(2)<<ans<<endl;
cout<<endl;
}
}
求周长模板:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
#define inf 1<<28
const ll base=13331;
const ll maxn=1e5+5;
#define lson k<<1
#define rson k<<1|1
#define mid ((l+r)>>1)
using namespace std;
struct line
{
ll x,y,h,lazy;
} p[maxn<<1];
struct node
{
ll sum,num,len;
bool lflag,rflag;
} tr[maxn<<3];
ll n,mx=-inf,mn=inf,cnt,ans,las;
void add(ll l,ll r,ll h,ll f)
{
p[++cnt].x=l;
p[cnt].y=r;
p[cnt].h=h;
p[cnt].lazy=f;
}
bool cmp(line a,line b)
{
return a.h<b.h||a.h==b.h&&a.lazy>b.lazy;
}
void pushup(ll k,ll l,ll r)
{
if(tr[k].sum)
{
tr[k].num=1;
tr[k].len=r-l+1;
tr[k].lflag=tr[k].rflag=1;
}
else if(l==r)
{
tr[k].len=0;
tr[k].num=0;
tr[k].lflag=tr[k].rflag=0;
}
else
{
tr[k].len=tr[lson].len+tr[rson].len;
tr[k].num=tr[lson].num+tr[rson].num;
if(tr[lson].rflag&&tr[rson].lflag)tr[k].num--;
tr[k].lflag=tr[lson].lflag;
tr[k].rflag=tr[rson].rflag;
}
}
void build(int k,int l,int r)
{
tr[k].lflag=tr[k].rflag=false;
tr[k].sum=0;
if(l==r)
return;
build(lson,l,mid);
build(rson,mid+1,r);
}
void modify(ll k,ll l,ll r,ll L,ll R,ll value)
{
if(l>=L&&r<=R)
{
tr[k].sum+=value;
pushup(k,l,r);
return;
}
if(L<=mid)modify(lson,l,mid,L,R,value);
if(R>mid)modify(rson,mid+1,r,L,R,value);
pushup(k,l,r);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
while(cin>>n&&n)
{
mx=-inf,mn=inf,cnt=0,ans=0,las=0;
build(1,1,n);
for(ll i=1; i<=n; i++)
{
ll x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
mx=max(mx,max(x1,x2));
mn=min(mn,min(x1,x2));
add(x1,x2,y1,1);
add(x1,x2,y2,-1);
}
if(mn<=0)
{
for(ll i=1; i<=cnt; i++)
{
p[i].x+=-mn+1;
p[i].y+=-mn+1;
}
mx-=mn;
}
sort(p+1,p+cnt+1,cmp);
for(ll i=1; i<=cnt; i++)
{
modify(1,1,mx,p[i].x,p[i].y-1,p[i].lazy);
while(p[i].h==p[i+1].h&&p[i].lazy==p[i+1].lazy)
{
i++;
modify(1,1,mx,p[i].x,p[i].y-1,p[i].lazy);
}
ans+=abs(tr[1].len-las);
las=tr[1].len;
ans+=tr[1].num*2*(p[i+1].h-p[i].h);
}
cout<<ans<<endl;
}
}