前言:最近购买了润滑脂和几个个性键帽,润滑脂用的太多大键稍微有点黏,但是我可以接受,钢丝声基本没有了,虽然没有拆下来卫星轴调试,但是效果还是有的,买了一个原厂高度的空格,好看是好看,用料也挺厚,但是形变非常严重,不过三十块要什么自行车,方向键是个手柄按键三角方块啥的透光键帽,用料也还行,但是字符有很明显的凹陷,看不出来但是摸起来就很明显,而且由于灯在轴的上方导致只有上面一半有光能透出来,但是我也不太在意
线段树update好题,首先把每个点转化为斜率,这样找一个递增序列即可,但是不同点在于这个递增序列不能挑,看到了就必须看到
这样怎么合并呢?首先对于一个区间左区间肯定全会看到,右区间如果全都矮于左区间最大值那肯定是看不到了,所以先记一个区间最大值,再记一个满足上面要求的区间上升序列长度,
如果右面有比左边大的怎么办呢?我们考虑右区间哪些会被看到,如果右区间的左区间最大值大于左区间的最大值,那么右区间的右区间一定可以全部看到,能看到的内容是右区间最长的合法序列在右区间的右区间的那部分,也就是len(x)-len(ls)
如果右区间的左区间最大值小于左区间的最大值,那么右区间的左区间一定不会被看到,只要去查右区间的右区间即可
#include<bits/stdc++.h> #define ls (x<<1) #define rs (x<<1|1) #define mid ((l+r)>>1) using namespace std; const int maxn=100009; int n,m; struct node{ int len; double mx; }t[maxn<<2]; double a[maxn]; void upd(int x){ t[x].mx=max(t[ls].mx,t[rs].mx); } int find(int x,int l,int r,double lx){ if(t[x].mx<=lx)return 0;//最大值小于查询的无贡献 if(l==r)return a[l]>lx;//叶子节点 if(a[l]>lx)return t[x].len;//最左端都大于了全部能看到 if(t[ls].mx>lx)return find(ls,l,mid,lx)+t[x].len-t[ls].len;//左区间能看到一部分那么t[x].len在右区间的那部分都能看到,递归查左区间 else return find(rs,mid+1,r,lx); } void change(int x,int l,int r,int pos,int val){ if(l==r){ a[l]=t[x].mx=1.0*val/pos; t[x].len=1; return; } if(pos<=mid)change(ls,l,mid,pos,val); else change(rs,mid+1,r,pos,val); upd(x); t[x].len=t[ls].len+find(rs,mid+1,r,t[ls].mx); } int main(){ scanf("%d%d",&n,&m); for(int i=1,p;i<=m;i++){ double x; scanf("%d%lf",&p,&x); change(1,1,n,p,x); printf("%d\n",t[1].len); } }
原文地址:https://www.cnblogs.com/superminivan/p/11620406.html
时间: 2024-10-10 04:28:48