P4198题解
题意:单点修改与查询前缀最大值个数。
维护
可见不管哪种情况都只需往一侧递归,复杂度为
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const double eps=1e-10;
ll n,q,x,y;
double maxn[400005];
ll ans[400005],val[400005];
bool leaf[400005];
inline ll get(ll k,double v){
if(leaf[k])return (maxn[k]-v>eps?1:0);
if(v-maxn[k<<1]>=eps)return get(k<<1|1,v);
else return 1ll*get(k<<1,v)+val[k<<1|1];
}
void build(ll k,ll l,ll r){
if(l==r){
leaf[k]=1;
return ;
}
ll mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
void modify(ll k,ll l,ll r,ll x,ll v){
if(l==r&&l==x){
maxn[k]=1.0*v/x;
if(maxn[k]>eps)ans[k]=1;
return ;
}
ll mid=(l+r)>>1;
if(x<=mid)modify(k<<1,l,mid,x,v);
else modify(k<<1|1,mid+1,r,x,v);
if(maxn[k<<1]-maxn[k<<1|1]>=eps)val[k<<1|1]=0;
else val[k<<1|1]=get(k<<1|1,maxn[k<<1]);
ans[k]=1ll*ans[k<<1]+val[k<<1|1];
maxn[k]=max(maxn[k<<1],maxn[k<<1|1]);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>q;
build(1,1,n);
while(q--){
cin>>x>>y;
modify(1,1,n,x,y);
cout<<ans[1]<<"\n";
}
return 0;
}