luogu P4198 building reconstruction

This question is maintained with a slope segment tree "mandatory" is incremented sequence number of elements

Others are not saying much, the main difficulty lies in how to update the number in the pushup

I was brain-dead on the direct use vector sequence stored at, then half of the update, measured only 10 minutes

In fact, you do not have to record sequence, as long as the maximum interval to record

But the problem facing so that there is no half way, so by looking at the solution to a problem they thought recursive processing

Specifically, increasing a count function, used to find the number of sequence elements satisfies the condition within a range

Initially only into the right interval, count (p * 2 + 1, mx [p * 2]), while satisfying the constraint must be greater than the maximum value of the left section;

Sub-situations:

  When l (p) == r (p), the recursion boundary, return mx (p)> k; (k is initially passed mx [p * 2]);

  When mx (p * 2) <= k, simply into the right section, return count (p * 2 + 1, k);

  else return len (p) -len (p * 2) + count (p * 2, k); (when mx [p * 2]> when k, the right section satisfy the condition, into the left section recursion, consider the left note shielding section, rather than len (p * 2 + 1));

( Too difficult, think )

On the code:

#include<iostream>
#include<cstdio>
using namespace std;
int n,m;
struct Node{
    int l,r,len;
    double mx;
    #define l(x) t[x].l
    #define r(x) t[x].r
    #define len(x) t[x].len
    #define mx(x) t[x].mx
}t[400010];
void build(int p,int l,int r){
    l(p)=l;r(p)=r;
    if(l==r){
        return;
    }
    int mid=(l+r)>>1;
    build(p*2,l,mid);build(p*2+1,mid+1,r);
}
int count(int p,double k){
    if(l(p)==r(p)) return mx(p)>k;
    if(mx(p*2)<=k) return count(p*2+1,k);
    else return len(p)-len(p*2)+count(p*2,k);
}
void change(int p,int x,double k){
    if(l(p)==r(p)){
        mx(p)=k;len(p)=1;
        return;
    }
    int mid=(l(p)+r(p))>>1;
    if(x<=mid) change(p*2,x,k);
    else change(p*2+1,x,k);
    mx(p)=max(mx(p*2),mx(p*2+1));
    len(p)=len(p*2)+count(p*2+1,mx(p*2));
}
int main(){
    scanf("%d%d",&n,&m);
    build(1,1,n);
    while(m--){
        double x,y;scanf("%lf%lf",&x,&y);double tan=y/x;
        change(1,x,tan);printf("%d\n",len(1));
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/SyhAKIOI/p/11617964.html