好菜啊,大原题都没做过
题意转换,相当于是 每次 单点修改后 求\(p[i] / i\)的单调递增子序列的最长长度
之后就不是很会了。。。。
参阅题解之后,相当于是 把\(push\_up\)的操作变复杂一点 加强它
然后就可以很快的实现单点修改 + 固定一个端点的 单调递增子序列的最大长度
代码实现也很简单
#include<bits/stdc++.h>
#define MAXN 100005
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
struct node{
int ans;
double mx;
}t[MAXN * 5];
int que(int rt , int l , int r , double v){
if(l == r)return t[rt].mx > v;
int mid = (l + r) >> 1;
if(t[rt << 1].mx <= v)return que(rt << 1 | 1 , mid + 1 , r , v);
else return que(rt << 1 , l , mid , v) + t[rt].ans - t[rt << 1].ans;
}
void update(int rt , int l , int r , int x , double v){
if(l == r){
t[rt].mx = v;
t[rt].ans = 1;
return;
}
int mid = (l + r) >> 1;
if(x <= mid)update(rt << 1 , l , mid , x , v);
else update(rt << 1 | 1 , mid + 1 , r , x , v);
t[rt].mx = max(t[rt << 1].mx , t[rt << 1 | 1].mx);
t[rt].ans = t[rt << 1].ans + que(rt << 1 | 1 , mid + 1 , r , t[rt << 1].mx);
}
int main(){
scanf("%d%d" , &n , &m);
int x,y;
for(int i = 1 ; i <= m ; i++){
cin>>x>>y;
update(1 , 1 , 1e5 , x , (y * 1.0) / (x * 1.0));
cout<<t[1].ans<<endl;
}
}