bzoj1957: building reconstruction (line segment tree)

Posted by Wizard4U on Thu, 30 Apr 2020 23:50:32 +0200

Title gate
. .

Solution:
It's a little metaphysical..
The interval maintains two values.
A value maintains how many of this range can be seen.. It's just that there's no influence outside the interval.
A value maintains the maximum slope of the interval.
So how to maintain the answer.
First, for an interval. It is divided into two sections: the left section and the right section.
The left is certainly not affected by the right.
So it can be inherited directly.
Then the right interval will be affected by the maximum value of the left interval.
Discuss according to the situation.
Let the right interval be x. The maximum value of the left interval is t.
If the maximum value of the left interval of x is < = t, then there is no left interval. The answer is all in the right interval. Continue to recurse.
If the maximum value of the left interval of x is > t, then t will not affect the right interval of x. Because they are all affected by the maximum value of the left interval of x.
The left interval is solved recursively because it is affected by t. And the right range is the answer of x - the left range.
Good question.

Code implementation:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
struct node {int l,r,lc,rc,c;double mx;}tr[210000];int len;
void bt(int l,int r) {
    int now=++len;tr[now].l=l;tr[now].r=r;tr[now].lc=tr[now].rc=-1;tr[now].c=0;tr[now].mx=0;
    if(l<r) {int mid=(l+r)/2;tr[now].lc=len+1;bt(l,mid);tr[now].rc=len+1;bt(mid+1,r);}
}
int get(int now,double tmp) {
    if(now==-1)return 0;
    if(tr[now].mx<=tmp)return 0;
    if(tr[now].l==tr[now].r&&tr[now].mx>tmp)return 1;
    int lc=tr[now].lc,rc=tr[now].rc;
    if(tr[lc].mx<=tmp)return get(rc,tmp);
    else return get(lc,tmp)+tr[now].c-tr[lc].c;
}
void change(int now,int x,double k) {
    if(tr[now].l==tr[now].r) {tr[now].c=1;tr[now].mx=k;return ;}
    int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
    if(x<=mid)change(lc,x,k);else change(rc,x,k);
    tr[now].mx=max(tr[lc].mx,tr[rc].mx);
    tr[now].c=tr[lc].c+get(rc,tr[lc].mx);
}
int main() {
    int n,m;scanf("%d%d",&n,&m);len=0;bt(1,n);
    for(int i=1;i<=m;i++) {
        int x,y;scanf("%d%d",&x,&y);double t=double(y)/double(x);
        change(1,x,t);printf("%d\n",tr[1].c);
    }
    return 0;
}