HDU 1542 扫描线:

用魔改线段树练一练手
毕竟刚学会,还不太熟

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;
    }
}
发布了254 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yangzijiangac/article/details/104916823