51nod 1562 玻璃切割(线段树区间合并)
来源:互联网 发布:网络广告公司铭心 编辑:程序博客网 时间:2024/05/01 16:31
1562 玻璃切割
题目来源: CodeForces
基准时间限制:1.5 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
收藏
关注
现在有一块玻璃,是长方形的(w 毫米× h 毫米),现在要对他进行切割。
切割的方向有两种,横向和纵向。每一次切割之后就会有若干块玻璃被分成两块更小的玻璃。在切割之后玻璃不会被移动。
现在想知道每次切割之后面积最大的一块玻璃是多少。
样例解释:
对于第四次切割,下面四块玻璃的面积是一样大的。都是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示例
样例输入14 3 4H 2V 2V 3V 1
Output示例
样例输出18442
时限1.5s 用线段树区间合并1.4秒艹过去了。。。
#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<vector>#include<map>#include <set>#include <bits/stdc++.h>using namespace std;const int N = 200000+10;typedef long long LL;struct node{ int l, r;}pw[N<<2], ph[N<<2];int sum1[N<<2], sum2[N<<2];void build1(int l,int r,int rt){ pw[rt].l=pw[rt].r=-1,sum1[rt]=0; if(l==r) return ; int mid=(l+r)/2; build1(l,mid,rt<<1); build1(mid+1,r,rt<<1|1); return ;}void update1(int l,int r,int rt,int x){ if(l==r) { pw[rt].l=pw[rt].r=x; return ; } int mid=(l+r)/2; if(x<=mid) update1(l,mid,rt<<1,x); else update1(mid+1,r,rt<<1|1,x); if(pw[rt<<1].l!=-1) pw[rt].l=pw[rt<<1].l; else pw[rt].l=pw[rt<<1|1].l; if(pw[rt<<1|1].r!=-1) pw[rt].r=pw[rt<<1|1].r; else pw[rt].r=pw[rt<<1].r; if(pw[rt<<1].l!=-1&&pw[rt<<1].r!=-1) sum1[rt]=sum1[rt<<1]; if(pw[rt<<1|1].l!=-1&&pw[rt<<1|1].r!=-1) sum1[rt]=max(sum1[rt<<1|1],sum1[rt]); if(pw[rt<<1].r!=-1&&pw[rt<<1|1].l!=-1) sum1[rt]=max(pw[rt<<1|1].l-pw[rt<<1].r,sum1[rt]); return ;}void build2(int l,int r,int rt){ ph[rt].l=ph[rt].r=-1; if(l==r) return ; int mid=(l+r)/2; build2(l,mid,rt<<1); build2(mid+1,r,rt<<1|1); return ;}void update2(int l,int r,int rt,int x){ if(l==r) { ph[rt].l=ph[rt].r=x; return ; } int mid=(l+r)/2; if(x<=mid) update2(l,mid,rt<<1,x); else update2(mid+1,r,rt<<1|1,x); if(ph[rt<<1].l!=-1) ph[rt].l=ph[rt<<1].l; else ph[rt].l=ph[rt<<1|1].l; if(ph[rt<<1|1].r!=-1) ph[rt].r=ph[rt<<1|1].r; else ph[rt].r=ph[rt<<1].r; if(ph[rt<<1].l!=-1&&ph[rt<<1].r!=-1) sum2[rt]=sum2[rt<<1]; if(ph[rt<<1|1].l!=-1&&ph[rt<<1|1].r!=-1) sum2[rt]=max(sum2[rt<<1|1],sum2[rt]); if(ph[rt<<1].r!=-1&&ph[rt<<1|1].l!=-1) sum2[rt]=max(ph[rt<<1|1].l-ph[rt<<1].r,sum2[rt]); return ;}char str[10];int main(){ int w, h, n; scanf("%d %d %d", &w, &h, &n); build1(0,w,1); build2(0,h,1); update1(0,w,1,0); update1(0,w,1,w); update2(0,h,1,0); update2(0,h,1,h); while(n--) { int x; scanf("%s %d",str, &x); if(str[0]=='V') { update1(0,w,1,x); } else { update2(0,h,1,x); } printf("%lld\n",(LL)sum1[1]*(LL)sum2[1]); } return 0;}
阅读全文
0 0
- 51nod 1562 玻璃切割(线段树区间合并)
- 51nod 1562 玻璃切割 【线段树】
- 51Nod-1562-玻璃切割
- 51Nod-1562-玻璃切割
- 51nod 1562 玻璃切割
- 51Nod 1562 玻璃切割 (set)
- 51nod-1562:玻璃切割(O(n)模拟)
- 51nod 1562玻璃切割(降维,反向处理)
- 51nod 1562 玻璃切割 (set+离线处理)
- 51nod1562-模拟&好题&链表|线段树-玻璃切割
- 51nod 1562 玻璃切割 (STL map+一点点的思考)
- 51NOD 1672 区间交 线段树
- 线段树 区间合并
- 线段树 区间合并
- 线段树 区间合并
- 线段树 区间合并
- 线段树-区间合并
- 谈区间合并线段树
- opencv-python中 boundingRect(cnt)以及cv2.rectangle用法
- iOS OC与Swift 项目调试神器
- netty源码深入研究(从客户端入手)第一篇
- java中枚举作用(用途)
- 微信API接口文档
- 51nod 1562 玻璃切割(线段树区间合并)
- Android学习笔记十九之Menu菜单
- 雷鸣的游戏人生(二) --- 新手报到
- 柯里化
- 开发手记--EditText maxLines无效和显示明文密码问题
- Android学习笔记二十之Toast吐司、Notification通知、PopupWindow弹出窗
- 前端之js-nodejs
- 使用Retrofit和Okhttp实现网络缓存。无网读缓存,有网根据过期时间重新请求
- jsp的隐含对象