Luo Gu 4198 building reconstruction (segment tree)

Immortal title.pb said to be routine questions? ? ?

First, only the top of the building is useful, and then to the slope of the increment.

I did nothing, the tree line.

Monotone certainly be recorded queue length interval \ (len \) . Of course, the whole can see the position of the write down will be more convenient, but the complexity of it burst.

Incidentally, again a maximum interval \ (MX \) .

Modify a single point, the leaves do well. Inquiry is the root node \ (len \) .

Difficulties in the pushup.

\ (mx \) regardless, just look \ (len \) .

First discovered, the leftmost and maximum values ​​can be seen.

When pushup, first of all from the left are still can be seen, the maximum number of the right to see the number and the left is related to the right to the left leaving only greater than the maximum number.

So we recursive pushup:

The parameters are: segment tree node number \ (o \) and can see the lower bound of \ (LWR \) (that is, keep only \ (> lwr \) number, and then seek Kan Bukan get)

If \ (mx_o \ Le LWR \) , can not see the whole range.

If \ (A_L> LWR \) , then the answer is \ (len_o \) (to see the number and not the lower bound no difference).

If \ (mx_ LSON} {\ Le LWR \) , then all left no son, the son of the right to recursively \ (pushup (rson, LWR) \) .

Otherwise, the maximum value of the left son certainly retained, then the right to see his son's number and no lower bound is no difference, the number is \ (len_o-LEN_ LSON} {\) . Left recursion Son to \ (a pushup (LSON, LWR) + len_o-LEN_ LSON} {\) .

Such a pushup is \ (O (\ log n-) \) .

Time complexity \ (O (m \ log ^ 2N) \) .


Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=400040;
#define ls o<<1
#define rs o<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
template<typename T>
inline void read(T &x){
    x=0;
    char ch=getchar();bool f=false;
    while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
    while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    if(f) x=-x;
}
int n,m,len[MAXN];
double a[MAXN],mx[MAXN];
inline void pushup1(int o){
    mx[o]=max(mx[ls],mx[rs]);
}
int pushup2(int o,int l,int r,double lwr){
    if(a[l]>lwr) return len[o];
    if(mx[o]<=lwr) return 0;
    int mid=(l+r)>>1;
    if(mx[ls]<=lwr) return pushup2(rson,lwr);
    else return pushup2(lson,lwr)+len[o]-len[ls];
}
inline void pushup(int o,int l,int r){
    pushup1(o);
    int mid=(l+r)>>1;
    len[o]=len[ls]+pushup2(rson,mx[ls]);
}
void update(int o,int l,int r,int p,double v){
    if(l==r) return void((mx[o]=v,len[o]=1));
    int mid=(l+r)>>1;
    if(mid>=p) update(lson,p,v);
    if(mid<p) update(rson,p,v);
    pushup(o,l,r);
}
int main(){
    read(n);read(m);
    while(m--){
        int x,y;
        read(x);read(y);
        update(1,1,n,x,a[x]=1.0*y/x);
        printf("%d\n",len[1]);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/1000Suns/p/11976014.html