51nod1562割玻璃
![](http://file.51nod.com/images/icon/star.png)
![](http://file.51nod.com/images/icon/plus.png)
现在有一块玻璃,是长方形的(w 毫米× h 毫米),现在要对他进行切割。
切割的方向有两种,横向和纵向。每一次切割之后就会有若干块玻璃被分成两块更小的玻璃。在切割之后玻璃不会被移动。
现在想知道每次切割之后面积最大的一块玻璃是多少。
样例解释:
![](https://img.51nod.com/upload/000FBF42/08D2CB5705AB76390000000000000015.png)
对于第四次切割,下面四块玻璃的面积是一样大的。都是2。
Input
单组测试数据。 第一行有三个整数 w,h,n (2≤w,h≤200000, 1≤n≤200000),表示玻璃在横向上长w 毫米,纵向上长h 毫米,接下来有n次的切割。 接下来有n行输入,每一行描述一次切割。 输入的格式是H y 或 V x。 H y表示横向切割,切割线距离下边缘y毫米(1≤y≤h-1)。 V x表示纵向切割,切割线距离左边缘x毫米(1≤x≤w-1)。 输入保证不会有两次切割是一样的。
Output
对于每一次切割,输出所有玻璃中面积最大的是多少。
Input示例
样例输入1 4 3 4 H 2 V 2 V 3 V 1
Output示例
样例输出1 8 4 4 2
这道题题意以及思路比较清楚:动态的维护行列上线段的最大值,每段线段可以在一次操作中被分成两段
一种思路:各种数据结构乱搞,反正200000,我开始用了一发set,超了一个点
另一种:区分线段比较难实现,不如合并,先把所有的线段都拆好,把操作到过来做,每次合并两个线段,统计最大值,写起来有点像DLX
发现思路和标程差不多,慢5倍,头文件的锅,貌似stdio.h超级快
先放个set的程序
#include <iostream> #include<cstdio> #include<algorithm> #include <set> #define ll long long using namespace std; set<ll> stw, sth; multiset<ll> valuew, valueh; ll read(){ ll ans=0; char last=' ',ch=getchar(); while(ch<'0' || ch>'9')last=ch,ch=getchar(); while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar(); if(last=='-')ans=-ans; return ans; } int main(){ ll w=read(), h=read(), n=read(); multiset<ll>::iterator it; valueh.insert(h); valuew.insert(w); stw.insert(0), stw.insert(w); sth.insert(0), sth.insert(h); ll fx=h,fy=w; while(n--){ char str[5]; ll x; scanf("%s", str); x=read(); if(str[0]=='H'){ it=sth.lower_bound(x); ll h1=*it; it--; ll h2=*it; it=valueh.find(h1-h2); valueh.erase(it); valueh.insert(x-h2); valueh.insert(h1-x); sth.insert(x); fx=*(valueh.rbegin()); }else{ it=stw.lower_bound(x); ll w1=*it; it--; ll w2=*it; it=valuew.find(w1-w2); valuew.erase(it); valuew.insert(x-w2); valuew.insert(w1-x); stw.insert(x); fy=*(valuew.rbegin()); } printf("%lld\n", fx*fy); } return 0; }
然后是第二种思路:
#include<stdio.h> #include<algorithm> #define ll long long #define maxn 200005 using namespace std; typedef struct { char ch; ll pos; } RES; typedef struct { ll l,val,r; } WORK; WORK H[maxn],V[maxn]; RES que[maxn]; ll fx[maxn],fy[maxn]; ll w,h,n,ansx,ansy,now; ll ans[maxn]; int main() { scanf("%lld %lld %lld",&w,&h,&n); fx[0]=fx[h]=fy[0]=fy[w]=1; for(int i=1;i<=n;i++) { scanf(" %c%lld",&que[i].ch,&que[i].pos); if(que[i].ch=='H') fx[que[i].pos]=1;else fy[que[i].pos]=1; } ansx=ansy=0; for(int i=now=0;i<=h;i++) { if(fx[i]==1) H[i].l=now,H[i].val=i-now,H[now].r=i,now=i,ansx=max(ansx,H[i].val); } H[h].r=h; for(int i=now=0;i<=w;i++) { if(fy[i]==1) V[i].l=now,V[i].val=i-now,V[now].r=i,now=i,ansy=max(ansy,V[i].val); } V[w].r=w; ans[n]=ansx*ansy; for(int i=n;i>=2;i--) { if(que[i].ch=='H') { H[H[que[i].pos].r].val=H[que[i].pos].val+H[H[que[i].pos].r].val; H[H[que[i].pos].l].r=H[que[i].pos].r; H[H[que[i].pos].r].l=H[que[i].pos].l; ansx=max(ansx,H[H[que[i].pos].r].val); }else { V[V[que[i].pos].r].val=V[que[i].pos].val+V[V[que[i].pos].r].val; V[V[que[i].pos].l].r=V[que[i].pos].r; V[V[que[i].pos].r].l=V[que[i].pos].l; ansy=max(ansy,V[V[que[i].pos].r].val); } ans[i-1]=ansx*ansy; } for(int i=1;i<=n;i++) printf("%lld\n",ans[i]); }