51nod3079 线段树进阶3

3079 线段树进阶3

小A的楼房外有一大片施工工地,工地上有nn栋待建的楼房。每天,这片工地上的房子拆了又建、建了又拆。他经常无聊地看着窗外发呆,数自己能够看到多少栋房子。

为了简化问题,我们考虑这些事件发生在一个二维平面上。小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中HiHi为第ii栋楼房的高度。如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线段相交,那么这栋楼房就被认为是可见的。

施工队的建造总共进行了m天。初始时,所有楼房都还没有开始建造,它们的高度均为0。在第i天,建筑队将会将横坐标为XiXi的房屋的高度变为Yi(高度可以比原来大—修建,也可以比原来小—拆除,甚至可以保持不变—建筑队这天什么事也没做)。请你帮小A数数每天在建筑队完工之后,他能看到多少栋楼房?

输入

第一行两个正整数 n,m
接下来 m 行,每行两个正整数 Xi,Yi

输出

m 行,第 i 行一个整数表示第 i 天过后小A能看到的楼房有多少栋

数据范围

对于100%的数据,1≤Xi≤n,1≤Yi≤10^9,n,m≤100000

输入样例

3 4
2 4
3 6
1 1000000000
1 1

输出样例

1
1
1
2

这里不给解析,直接给代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int Maxn=100010;
inline char getch()
{
	static const int Buf=1048576;
	static char buf[Buf+1],*head=buf,*tail=buf;
	if(head==tail) *(tail=(head=buf)+fread(buf,1,Buf,stdin))=0;
	return *head++;
}
void read(int &ret)
{
	static char ch;
	ret=0;ch=getch();
	while(ch<'0' || ch>'9') ch=getch();
	while('0'<=ch && ch<='9') ret=ret*10+ch-'0',ch=getch();
}
inline void putch(char ch,int flag=0)
{
	static const int Buf=1048576;
	static char buf[Buf+1],*head=buf,*tail=buf+Buf;
	if(head==tail || flag) fwrite(buf,1,head-buf,stdout),head=buf;
	*head++=ch;
}
void write(int x)
{
	static int a[12],len;
	if(x==0){ putch('0'); }
	len=0;
	while(x) a[++len]=x%10,x/=10;
	while(len) putch(a[len--]+'0');
}
struct Treenode
{
	double maxn;int cnt;
}node[Maxn<<2];
int n,m;
int update(int x,int ll,int rr,double val)
{
	if(ll>=rr) return node[x].maxn>val;
	if(val<node[x<<1].maxn) return node[x].cnt-node[x<<1].cnt+update(x<<1,ll,ll+rr>>1,val);
	else return update(x<<1|1,ll+rr+2>>1,rr,val);
}
void modify(int x,int ll,int rr,int p,double v)
{
	if(ll==rr)
	{
		node[x].cnt=1;node[x].maxn=v;
		return;
	}
	int mid=ll+rr>>1;
	if(p<=mid) modify(x<<1,ll,mid,p,v);
	else modify(x<<1|1,mid+1,rr,p,v);
	node[x].maxn=max(node[x<<1].maxn,node[x<<1|1].maxn);
	node[x].cnt=node[x<<1].cnt+update(x<<1|1,ll+rr+2>>1,rr,node[x<<1].maxn);
}
int main()
{
	read(n);read(m);
	for(int x,y,i=1;i<=m;i++)
	{
		read(x);read(y);
		modify(1,1,n,x,1.0*y/x);
		write(node[1].cnt);putch('\n');
	}
	putch(0,1);
	return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值