AC日记——玻璃切割 51nod 1562

玻璃切割

思路:

  并查集;

  离线操作;

  先把每次切割都存下来;

  然后从后面不断合并切割;

  然后每次更新最大长和宽;

  记录答案;

  要开longlong;

来,上代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define maxn 400005
#define ll long long

struct OperType {
    ll l,r,x;
};
struct OperType hh[maxn],ww[maxn];

struct CutType {
    ll x,id;
};
struct CutType qh[maxn],qw[maxn];

ll f1[maxn],f2[maxn],w,h,n,totw,toth,dis1[maxn],dis2[maxn];
ll answ,ansh,ans[maxn];

bool ty[maxn];

inline void in(ll &now)
{
    char Cget=getchar();now=0;
    while(Cget>'9'||Cget<'0') Cget=getchar();
    while(Cget>='0'&&Cget<='9')
    {
        now=now*10+Cget-'0';
        Cget=getchar();
    }
}

ll find1(ll x)
{
    if(f1[x]==x) return f1[x];
    f1[x]=find1(f1[x]);
    return f1[x];
}

ll find2(ll x)
{
    if(f2[x]==x) return f2[x];
    f2[x]=find2(f2[x]);
    return f2[x];
}

bool cmp(CutType aa,CutType bb)
{
    return aa.x<bb.x;
}

int main()
{
    in(w),in(h),in(n);char ch[3];
    for(ll i=1;i<=n;i++)
    {
        scanf("%s",ch);
        if(ch[0]=='H')
        {
            ty[i]=true;
            in(hh[++toth].x);
            qh[toth].x=hh[toth].x;
            qh[toth].id=toth,f1[toth]=toth;
        }
        else
        {
            in(ww[++totw].x);
            qw[totw].x=ww[totw].x;
            qw[totw].id=totw,f2[totw]=totw;
        }
    }
    sort(qw+1,qw+totw+1,cmp);
    sort(qh+1,qh+toth+1,cmp);
    ll pos=0;f1[toth+1]=toth+1,f2[totw+1]=totw+1;
    for(ll i=1;i<=toth;i++)
    {
        dis1[i]=qh[i].x-pos,pos=qh[i].x,ansh=max(dis1[i],ansh);
        hh[qh[i].id].l=i,hh[qh[i].id].r=i+1;
    }
    dis1[toth+1]=h-pos,ansh=max(ansh,dis1[toth+1]),pos=0;
    for(ll i=1;i<=totw;i++)
    {
        dis2[i]=qw[i].x-pos,pos=qw[i].x,answ=max(dis2[i],answ);
        ww[qw[i].id].l=i,ww[qw[i].id].r=i+1;
    }
    dis2[totw+1]=w-pos,answ=max(answ,dis2[totw+1]);
    ans[n]=answ*ansh;
    for(ll i=n;i>1;i--)
    {
        if(ty[i])
        {
            ll x=find1(hh[toth].l),y=find1(hh[toth].r);
            if(x!=y)
            {
                dis1[x]+=dis1[y],f1[y]=x;
                ansh=max(ansh,dis1[x]);
            }
            toth--;
        }
        else
        {
            ll x=find2(ww[totw].l),y=find2(ww[totw].r);
            if(x!=y)
            {
                dis2[x]+=dis2[y],f2[y]=x;
                answ=max(answ,dis2[x]);
            }
            totw--;
        }
        ans[i-1]=answ*ansh;
    }
    for(ll i=1;i<=n;i++) printf("%lld
",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6769153.html