1. 程式人生 > 其它 >lgP4198 樓房重建

lgP4198 樓房重建

好菜啊,大原題都沒做過

題意轉換,相當於是 每次 單點修改後 求\(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;
	}
	
	
}