51nod 1562 玻璃切割 【线段树】
2017-05-01 12:06
155 查看
1562 玻璃切割
题目来源: CodeForces
基准时间限制:1.5 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
![](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
Output
Input示例
Output示例
线段树--------------
以x,y 分别建线段树---来寻找最大区间
代码:
#include<stdio.h>
int max(int x,int y)
{
if (x>y)
return x;
return y;
}
struct Tree{
int l,r,shu,lnode,rnode;
}HH[550000],WW[550000];
void createW(int l,int r,int x)
{
WW[x].l=l;WW[x].r=r;
WW[x].shu=r-l;
WW[x].lnode=r;
WW[x].rnode=l;
if (l+1<r)
{
int m=(l+r)>>1;
createW(l,m,x*2);
createW(m,r,x*2+1);
}
}
void geW(int x,int p)
{
if (WW[x].lnode>p)
WW[x].lnode=p;
if (WW[x].rnode<p)
WW[x].rnode=p;
WW[x].shu=max(WW[x].r-WW[x].rnode,WW[x].lnode-WW[x].l);
if (WW[x].l+1<WW[x].r)
{
int m=(WW[x].l+WW[x].r)>>1;
if (p<=m)
geW(x*2,p);
if (p>=m)
geW(x*2+1,p);
WW[x].shu=max(WW[x*2].shu,WW[x*2+1].shu);
int a,b;
a=WW[x*2].rnode;
b=WW[x*2+1].lnode;
if (b-a>WW[x].shu)
WW[x].shu=b-a;
}
}
void createH(int l,int r,int x)
{
HH[x].l=l;HH[x].r=r;
HH[x].shu=r-l;
HH[x].lnode=r;
HH[x].rnode=l;
if (l+1<r)
{
int m=(l+r)>>1;
createH(l,m,x*2);
createH(m,r,x*2+1);
}
}
void geH(int x,int p)
{
if (HH[x].lnode>p)
HH[x].lnode=p;
if (HH[x].rnode<p)
HH[x].rnode=p;
HH[x].shu=max(HH[x].r-HH[x].rnode,HH[x].lnode-HH[x].l);
if (HH[x].l+1<HH[x].r)
{
int m=(HH[x].l+HH[x].r)>>1;
if (p<=m)
geH(x*2,p);
if (p>=m)
geH(x*2+1,p);
HH[x].shu=max(HH[x*2].shu,HH[x*2+1].shu);
int a,b;
a=HH[x*2].rnode;
b=HH[x*2+1].lnode;
if (b-a>HH[x].shu)
HH[x].shu=b-a;
}
}
int main()
{
int w,h,n;
scanf("%d%d%d",&w,&h,&n);
createW(0,w,1);
createH(0,h,1);
char ch[5];
int a,b;
long long aa,bb;
for (int i=0;i<n;i++)
{
scanf("%s%d",ch,&a);
if (ch[0]=='V')
geW(1,a);
else
geH(1,a);
aa=WW[1].shu;
bb=HH[1].shu;
printf("%lld\n",aa*bb);
}
return 0;
}
题目来源: CodeForces
基准时间限制:1.5 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
![](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
线段树--------------
以x,y 分别建线段树---来寻找最大区间
代码:
#include<stdio.h>
int max(int x,int y)
{
if (x>y)
return x;
return y;
}
struct Tree{
int l,r,shu,lnode,rnode;
}HH[550000],WW[550000];
void createW(int l,int r,int x)
{
WW[x].l=l;WW[x].r=r;
WW[x].shu=r-l;
WW[x].lnode=r;
WW[x].rnode=l;
if (l+1<r)
{
int m=(l+r)>>1;
createW(l,m,x*2);
createW(m,r,x*2+1);
}
}
void geW(int x,int p)
{
if (WW[x].lnode>p)
WW[x].lnode=p;
if (WW[x].rnode<p)
WW[x].rnode=p;
WW[x].shu=max(WW[x].r-WW[x].rnode,WW[x].lnode-WW[x].l);
if (WW[x].l+1<WW[x].r)
{
int m=(WW[x].l+WW[x].r)>>1;
if (p<=m)
geW(x*2,p);
if (p>=m)
geW(x*2+1,p);
WW[x].shu=max(WW[x*2].shu,WW[x*2+1].shu);
int a,b;
a=WW[x*2].rnode;
b=WW[x*2+1].lnode;
if (b-a>WW[x].shu)
WW[x].shu=b-a;
}
}
void createH(int l,int r,int x)
{
HH[x].l=l;HH[x].r=r;
HH[x].shu=r-l;
HH[x].lnode=r;
HH[x].rnode=l;
if (l+1<r)
{
int m=(l+r)>>1;
createH(l,m,x*2);
createH(m,r,x*2+1);
}
}
void geH(int x,int p)
{
if (HH[x].lnode>p)
HH[x].lnode=p;
if (HH[x].rnode<p)
HH[x].rnode=p;
HH[x].shu=max(HH[x].r-HH[x].rnode,HH[x].lnode-HH[x].l);
if (HH[x].l+1<HH[x].r)
{
int m=(HH[x].l+HH[x].r)>>1;
if (p<=m)
geH(x*2,p);
if (p>=m)
geH(x*2+1,p);
HH[x].shu=max(HH[x*2].shu,HH[x*2+1].shu);
int a,b;
a=HH[x*2].rnode;
b=HH[x*2+1].lnode;
if (b-a>HH[x].shu)
HH[x].shu=b-a;
}
}
int main()
{
int w,h,n;
scanf("%d%d%d",&w,&h,&n);
createW(0,w,1);
createH(0,h,1);
char ch[5];
int a,b;
long long aa,bb;
for (int i=0;i<n;i++)
{
scanf("%s%d",ch,&a);
if (ch[0]=='V')
geW(1,a);
else
geH(1,a);
aa=WW[1].shu;
bb=HH[1].shu;
printf("%lld\n",aa*bb);
}
return 0;
}
相关文章推荐
- 51nod 1562 玻璃切割(线段树区间合并)
- 51Nod 1562 玻璃切割 (set)
- 51nod 1562 玻璃切割
- 51Nod-1562-玻璃切割
- 51nod-1562:玻璃切割(O(n)模拟)
- 51nod 1562 玻璃切割 (STL map+一点点的思考)
- 51nod 1562玻璃切割(降维,反向处理)
- 51Nod-1562-玻璃切割
- AC日记——玻璃切割 51nod 1562
- 51nod 1562 玻璃切割
- 51nod1562-模拟&好题&链表|线段树-玻璃切割
- 51nod:加农炮(线段树+单调性)
- 51nod 1593 公园晨跑 | ST表(线段树?)思维题
- 51nod 1819 黑白树 V2 树链剖分维护轻儿子信息+线段树
- 51Nod 1174 区间中最大的数 线段树
- 51nod 1631 线段树
- 51nod 1672-区间交(线段树)
- 51nod_1174 区间中最大的数(线段树模板)
- 51nod 1208 && POJ 2482:Stars in Your Window【普通线段树】
- 51Nod 1174 区间中最大的数<线段树>