[12.6] Diary

12.6 diary

Segment tree

  1. HDU1540: Modify a single point where the longest single point + continuum

Ideas : yesterday with the set (balanced tree) do, find a simple number, or learn about the practice of tree line. But after school finished discovery, really a segment tree is still very necessary, if the interval is modified, then hung up the balance of the tree, can only be used to process the tree line. Moreover, there may be sections where the longest continuous interval topics like.

Configuration : Each node storing four values, lm current recording interval length of the left point to the left end point of the longest interval 1, rm current recording interval to the right end of the right end point of a longest length section, mm recording the longest length of the current interval is an interval, COL auxiliary array, if all the current interval is 1, col = 1, if the current section are all 0, then col = 0, else col = -1. Obviously col mm can be directly used to replace, so simple written words to store three values can be.

pushup :( core operating)

  1. lm: If left his son a full one, the lm [id] = lm is [id * 2] + lm [id * 2 + 1] (as it will be extended to the right section), otherwise lm [id] = lm [id * 2 ]
  2. rm: If the right son all 1, then rm [id] = rm is [id * 2] + rm [id * 2 + 1] (as it will be extended to the right section), or rm [id] = rm [id * 2 +1]
  3. mm: maximum of three values: mm [id] = max (mm [id * 2], mm [id * 2 + 1], rm [id * 2] + lm [id * 2 + 1])
  4. col: mm is used to push values. If mm = 0 then the col = 0, if mm = r-l + 1 then the col = 1, else col = -1.

Here there is no pushdown operation.

Operate : a single point of direct violence modify, remember pushup

Query : is more complex. The core idea is: check whether the target point may be across the range included two sons, if you can, seek answers directly, or recursive.

To achieve the following specific, first determine the target point pos son left or right son. If left his son, then the judge rm [id * 2] whether may contain pos, if included, the return rm [id * 2] + lm [id * 2 + 1]. Otherwise, the recursive left son. If the right son, it is judged lm [id * 2 + 1] if the POS may contain, if included, return rm [id * 2] + lm [id * 2 + 1]. Otherwise, the right recursive son.

Greedy easy to know, if included, return directly to the length, it is the longest interval.

#include<bits/stdc++.h>
#define mid (l+r)/2
using namespace std;
const int M=5e4+20;
int lm[4*M],rm[4*M],mm[4*M],col[4*M];
inline void pushup(int id,int l,int r){
    if (col[id*2]==1)
        lm[id]=lm[id*2]+lm[id*2+1];
    else
        lm[id]=lm[id*2];
    if (col[id*2+1]==1)
        rm[id]=rm[id*2+1]+rm[id*2];
    else
        rm[id]=rm[id*2+1];
    mm[id]=max(max(mm[id*2],mm[id*2+1]),rm[id*2]+lm[id*2+1]);
    if (mm[id]==0)
        col[id]=0;
    else if (mm[id]==r-l+1)
        col[id]=1;
    else
        col[id]=-1;
}
void build(int id,int l,int r){
    col[id]=1;
    lm[id]=rm[id]=mm[id]=r-l+1;
    if (l==r)
        return;
    build(id*2,l,mid);
    build(id*2+1,mid+1,r);
    pushup(id,l,r);
}
void operate(int id,int l,int r,int pos,int x){
    if (l==r){
        if (x)
            lm[id]=rm[id]=mm[id]=col[id]=1;
        else
            lm[id]=rm[id]=mm[id]=col[id]=0;
        return;
    }
    if(pos<=mid)
        operate(id*2,l,mid,pos,x);
    else
        operate(id*2+1,mid+1,r,pos,x);
    pushup(id,l,r);
}
int query(int id,int l,int r,int pos){
    if(l==r)
        return mm[id];
    if (pos<=mid){
        if (pos+rm[id*2]>mid)
            return rm[id*2]+lm[id*2+1];
        else
            return query(id*2,l,mid,pos);
    }
    else{
        if (mid+lm[id*2+1]>=pos)
            return rm[id*2]+lm[id*2+1];
        else
            return query(id*2+1,mid+1,r,pos);
    }
}
stack<int> stk;
int main(){
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        build(1,1,n);
        for(int i=1;i<=m;++i){
            char s[2];
            int x;
            scanf("%s",s);
            if (s[0]=='R')
                operate(1,1,n,stk.top(),1),stk.pop();   
            else{
                scanf("%d",&x);
                if (s[0]=='D')
                    operate(1,1,n,x,0),stk.push(x);
                else
                    printf("%d\n",query(1,1,n,x));
            }
        }
    }
    return 0;
}

to sum up

Recently it is too busy, I cried, and quickly learn. Another week, fight!

Guess you like

Origin www.cnblogs.com/diorvh/p/12001358.html
Recommended