lgP4198 樓房重建
阿新 • • 發佈:2021-11-02
好菜啊,大原題都沒做過
題意轉換,相當於是 每次 單點修改後 求\(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; } }