这题很明显需要维护最大斜率(当然选择线段树辣)。。然后维护完怎么保证单调就很让人烦恼了。。
假设有2段已经符合要求的单调序列要合并时,可以想到应该要把左段的最大值求出来,再对右段进行二分查找。。
所以合并时还要加多一个二分查找,边找边加上区间就可以。。
可以肯定的合并的时候左段肯定是整段加上,而右段是经过消减的,所以在加上区间时应该用整段减去左段,不然直接加右段会将消减去的部分再重新加回来。。(一个比较隐晦的细节。。
/**
* ┏┓ ┏┓
* ┏┛┗━━━━━━━┛┗━━━┓
* ┃ ┃
* ┃ ━ ┃
* ┃ > < ┃
* ┃ ┃
* ┃... ⌒ ... ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ 神兽保佑,代码无bug
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-12
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define mid (x+y>>1)
#define NM 2005
#define nm 105
#define pi 3.1415926535897931
using namespace std;
const ll inf=1000000007;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}
int n,m,_x,_y;
struct node{
node*l,*r;
int x,y,s;double m;
node(int x,int y,node*l=0,node*r=0):x(x),y(y),l(l),r(r),s(0),m(0){}
int get(double t){
if(x==y)return m>t+eps;
return l->m>t+eps?s-l->s+l->get(t):r->get(t);
}
void upd(){s=l->s+r->get(l->m);m=max(l->m,r->m);}
void mod(){
if(x==y){m=(double)_y/x;s=1;return;}
if(_x<=mid)l->mod();else r->mod();upd();
}
}*root;
node*build(int x,int y){return x==y?new node(x,y):new node(x,y,build(x,mid),build(mid+1,y));}
int main(){
freopen("data.in","r",stdin);
n=read();m=read();
root=build(1,n);
while(m--){
_x=read();_y=read();
root->mod();
printf("%d\n",root->s);
}
return 0;
}
2957: 楼房重建
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2951 Solved: 1372
[ Submit][ Status][ Discuss]
Description
小A的楼房外有一大片施工工地,工地上有N栋待建的楼房。每天,这片工地上的房子拆了又建、建了又拆。他经常无聊地看着窗外发呆,数自己能够看到多少栋房子。
为了简化问题,我们考虑这些事件发生在一个二维平面上。小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度。如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线段相交,那么这栋楼房就被认为是可见的。
施工队的建造总共进行了M天。初始时,所有楼房都还没有开始建造,它们的高度均为0。在第i天,建筑队将会将横坐标为Xi的房屋的高度变为Yi(高度可以比原来大---修建,也可以比原来小---拆除,甚至可以保持不变---建筑队这天什么事也没做)。请你帮小A数数每天在建筑队完工之后,他能看到多少栋楼房?
Input
第一行两个正整数N,M
接下来M行,每行两个正整数Xi,Yi
Output
M行,第i行一个整数表示第i天过后小A能看到的楼房有多少栋
Sample Input
3 4
2 4
3 6
1 1000000000
1 1
Sample Output
1
1
1
2
数据约定
对于所有的数据1<=Xi<=N,1<=Yi<=10^9
N,M<=100000