bzoj2957 Building reconstruction - line segment tree

Subject: https://www.lydsy.com/JudgeOnline/problem.php?id=2957

The line segment tree maintains the slope from the origin to the roof of the building, and you can know that the answer is the number of increasing slopes from the origin;

Record an mx array representing the largest slope on this segment, bisection, classification discussion, recursive solution;

And if you want to take the length of rs, not directly take tr[rs], but subtract tr[ls] from the total length, because you can't start from the starting point of the segment on the right...

code show as below:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const MAXN=100005;
int n,m,tr[MAXN<<2];
double xl[MAXN],mx[MAXN<<2];
int find(int x,int l,int r,double w)
{
    if(l==r)return xl[l]>w;
    int ls=(x<<1),rs=(x<<1|1);
    int mid=((l+r)>>1);
    if(mx[ls]>w)return tr[x]-tr[ls]+find(ls,l,mid,w);
    return find(rs,mid+1,r,w);
}
void pushup(int x,int l,int r)
{
    int mid=((l+r)>>1);
    int ls=(x<<1),rs=(x<<1|1);
    if(mx[ls]>=mx[rs])tr[x]=tr[ls],mx[x]=mx[ls];
    else if(mx[ls]<xl[mid+1])tr[x]=tr[ls]+tr[rs],mx[x]=mx[rs];
    else
    {
        tr[x]=tr[ls]+find(rs,mid+1,r,mx[ls]);
        mx[x]=mx[rs];
    }
}
void add(int nw,int L,int R,int l,int r,double w)
{
    if(l==r)
    {
        tr[nw] = 1 ;mx[nw]=w; // !!!Be careful not to write nw as l 
        return ;
    }
    int mid=((l+r)>>1);
    if(mid>=L)add(nw<<1,L,R,l,mid,w);
    if(mid<R)add(nw<<1|1,L,R,mid+1,r,w);
    pushup(nw,l,r);
}
intmain ()
{
    scanf("%d%d",&n,&m);
    for(int i=1,x;i<=m;i++)
    {
        double y;
        scanf("%d%lf",&x,&y);
        xl[x]=y/x;
        add(1,x,x,1,n,xl[x]);
        printf("%d\n",tr[1]);
    }
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325012986&siteId=291194637