题面
看到的楼房数肯定是不降的
于是我们考虑上线段树
考虑Query
左边的肯定能一览无余。所以若右边没有左边最高的高,就看不到了;反之则加上右边的答案
考虑Update
如果新增的没有原来的高,卵用没有,把极值改了就好了
如果新增的比原来的高,它左边的仍然能看到,减去它右边原来能看到,后来没它高的一段
考虑精度
float是不够的,而且要注意中途 double / long double 不能断
否则就只有和爆扫一样的40分
Code : 813ms / 10.74MB / 1.02KB
1 #include<stdio.h>
2 #define ld long double
3 #define mid ((l+r)>>1)
4 #define lson (rt<<1)
5 #define rson (rt<<1|1)
6 #define For(i,a,b) for(register int i=(a);i<=(b);i++)
7 using namespace std;
8 const int maxn=1e5+10;
9 int n,q;
10 struct T{
11 int ans;ld xl;
12 }tree[maxn<<2];
13 inline ld max(ld a,ld b){return a>b?a:b;}
14 inline int query(int l,int r,int rt,ld now){
15 if(tree[rt].xl<=now) return 0;
16 if(l==r) return tree[rt].xl>now;
17 if(tree[lson].xl<now){
18 return query(mid+1,r,rson,now);
19 }
20 return query(l,mid,lson,now)+tree[rt].ans-tree[lson].ans;
21 }
22 inline void update(int l,int r,int rt,int wnt,ld now){
23 if(l==wnt&&r==wnt){
24 tree[rt].xl=now,tree[rt].ans=1;
25 return ;
26 }
27 if(wnt<=mid){
28 update(l,mid,lson,wnt,now);
29 }else{
30 update(mid+1,r,rson,wnt,now);
31 }
32 tree[rt].xl=max(tree[lson].xl,tree[rson].xl);
33 tree[rt].ans=query(mid+1,r,rson,tree[lson].xl)+tree[lson].ans;
34 }
35 signed main(){
36 scanf("%d%d",&n,&q);
37 while(q--){
38 int x,y;scanf("%d%d",&x,&y);
39 update(1,n,1,x,(ld)1.00*y/x);
40 printf("%d
",tree[1].ans);
41 }
42 }