小A的楼房外有一大片施工工地,工地上有N栋待建的楼房。每天,这片工地上的房子拆了又建、建了又拆。他经常无聊地看着窗外发呆,数自己能够看到多少栋房子。
为了简化问题,我们考虑这些事件发生在一个二维平面上。小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度。如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线段相交,那么这栋楼房就被认为是可见的。
施工队的建造总共进行了M天。初始时,所有楼房都还没有开始建造,它们的高度均为0。在第i天,建筑队将会将横坐标为Xi的房屋的高度变为Yi(高度可以比原来大—修建,也可以比原来小—拆除,甚至可以保持不变—建筑队这天什么事也没做)。请你帮小A数数每天在建筑队完工之后,他能看到多少栋楼房?
其实就是让你去求单调栈
如果这个问题是静态的话,单调栈就可以很好的解决,但问题是现在带修改,所以我们需要去用线段树维护单调栈
每次在
x
i
x_i
xi的位置上修改为
y
i
/
x
i
y_i / x_i
yi/xi,然后暴力修改合并即可
#pragma GCC optimize(3) #include <bits/stdc++.h> #define debug(x) cout<<#x<<":"<<x<<endl; #define dl(x) printf("%lld\n",x); #define di(x) printf("%d\n",x); #define _CRT_SECURE_NO_WARNINGS #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second #define SZ(x) ((int)(x).size()) using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> PII; typedef vector<int> VI; const int INF = 0x3f3f3f3f; const int N = 2e5 + 10; const ll mod = 1000000007; const double eps = 1e-9; const double PI = acos(-1); template<typename T>inline void read(T &a) { char c = getchar(); T x = 0, f = 1; while (!isdigit(c)) {if (c == '-')f = -1; c = getchar();} while (isdigit(c)) {x = (x << 1) + (x << 3) + c - '0'; c = getchar();} a = f * x; } int gcd(int a, int b) {return (b > 0) ? gcd(b, a % b) : a;} int n,m; struct Node{ int l,r,ans; double x; }tr[N * 4]; void build(int u,int l,int r){ tr[u].l = l,tr[u].r = r; if(l == r){ return; } int mid = l + r >> 1; build(u << 1,l,mid),build(u << 1 | 1,mid + 1,r); } int query(int u,double k){ if(tr[u].l == tr[u].r) return tr[u].x > k; if(tr[u << 1].x <= k) return query(u << 1 | 1,k); else return tr[u].ans - tr[u << 1].ans + query(u << 1,k); } void push(int u){ tr[u].x = max(tr[u << 1].x,tr[u << 1 | 1].x); tr[u].ans = tr[u << 1].ans + query(u,tr[u << 1].x); } void modify(int u,int p,double k){ if(tr[u].l == tr[u].r){ tr[u].ans = 1; tr[u].x = k; return; } int mid = tr[u].l + tr[u].r >> 1; if(p <= mid) modify(u << 1,p,k); else modify(u << 1 | 1,p,k); push(u); } int main() { read(n),read(m); build(1,1,n); for(int i = 1;i <= m;i++){ double x,y; scanf("%lf%lf",&x,&y); modify(1,x,y / x); di(tr[1].ans); } return 0; } /** * ┏┓ ┏┓+ + * ┏┛┻━━━┛┻┓ + + * ┃ ┃ * ┃ ━ ┃ ++ + + + * ████━████+ * ◥██◤ ◥██◤ + * ┃ ┻ ┃ * ┃ ┃ + + * ┗━┓ ┏━┛ * ┃ ┃ + + + +Code is far away from * ┃ ┃ + bug with the animal protecting * ┃ ┗━━━┓ 神兽保佑,代码无bug * ┃ ┣┓ * ┃ ┏┛ * ┗┓┓┏━┳┓┏┛ + + + + * ┃┫┫ ┃┫┫ * ┗┻┛ ┗┻┛+ + + + */