【BZOJ2957】—楼房重建(线段树维护单调序列)
发现如果左边比右边最高的高的话左边肯定右边的就没用了
然后就是一个单调栈
用线段树维护一下就可以了
具体可以看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline int read(){
char ch=getchar();
int res=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
return res*f;
}
const int N=100005;
int ans[N<<2],n,m;
double tr[N<<2];
#define lc (u<<1)
#define rc ((u<<1)|1)
#define mid ((l+r)>>1)
inline int query(int u,int l,int r,double k){
if(l==r)return tr[u]>k;
if(tr[lc]<=k)return query(rc,mid+1,r,k);
else return ans[u]-ans[lc]+query(lc,l,mid,k);
}
inline void pushup(int u,int l,int r){
tr[u]=max(tr[lc],tr[rc]);
ans[u]=ans[lc]+query(rc,mid+1,r,tr[lc]);
}
inline void update(int u,int l,int r,int p,double k){
if(l==r){tr[u]=k,ans[u]=1;return;}
if(p<=mid)update(lc,l,mid,p,k);
else update(rc,mid+1,r,p,k);
pushup(u,l,r);
}
int main(){
n=read(),m=read();
for(int i=1;i<=m;i++){
double x=read(),y=read();
update(1,1,n,x,y/x);cout<<ans[1]<<'\n';
}
}