# Merging investigation of P4198 building reconstruction line segment tree

Topic entry

In fact, this problem is not easy to see at the beginning. This is the problem of the line segment tree, but when we see the modification, nine times out of ten we are investigating the line segment tree. When we see whether the floor required by the problem surface can be seen, we think that the line segment tree maintains the slope (because only the floor with a large and high slope with the original point can be seen), The difficulty of this problem lies in how to maintain this line segment tree. The main limiting factor in this problem lies in the point closest to the origin, that is, the left half interval. Each point maintains the floors with only [l, R] interval. How many buildings can we see, that is, all floors except these intervals do not exist. The most difficult thing is how to merge these floors.

Let me introduce the idea of the big man first (konjaku is too tired to write)

From the valley of Los Angeles Nemlit mogul

Finally, the code ends the problem

```#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std ;

const int N = 1e5 + 10 ;

int n , m ;
{
char c ;
int res = 0 , flag = 1 ;
c = getchar() ;
while(!isdigit(c))
{
if(c == '-') flag = -1 ;
c = getchar() ;
}
while(isdigit(c))
{
res = (res << 1) + (res << 3) + (c ^ 48) ;
c = getchar() ;
}
return res * flag ;
}

struct Node
{
int l , r , cnt ;
double val ; // Slope
} tr[N * 4] ;

void build(int u , int l , int r)
{
tr[u] = {l , r , 0 , 0} ;
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 val)
{
if(tr[u].val <= val) return 0 ;
if(tr[u].l == tr[u].r) return 1 ;
if(tr[u << 1].val <= val) return query(u << 1 | 1 , val) ;
return query(u << 1 , val) + tr[u].cnt - tr[u << 1].cnt ;
}
void change(int u , int pos , double x)
{
if(tr[u].l == tr[u].r)
{
tr[u].val = x ;
tr[u].cnt = 1 ;
return ;
}
int mid = tr[u].l + tr[u].r >> 1;
if(pos <= mid) change(u << 1 , pos , x) ;
else change(u << 1 | 1 , pos , x) ;
tr[u].val = max(tr[u << 1].val , tr[u << 1 | 1].val) ;
tr[u].cnt = tr[u << 1].cnt + query(u << 1 | 1 , tr[u << 1].val) ;
}
int main(void)
{
build(1 , 1 , n) ;
for(int i = 1 ; i <= m ; i ++)
{
int x , h ;