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\n",ans[i]); return 0; }