(J) uva1400 * (query interval to try and locate) (problem)

uva1400 "Ray, Pass me the dishes!"

As part you do not understand when reading this article, please ask in the comments section, or jump  tree line general introduction

 

This title is Black title in luogu it ... QAQ (but it is a segment tree template title ah qwq)

 

Title effect: given a sequence of length n is an integer D, to answer to the inquiry of m, the inquiry (a, b) to find the (x, y) such that a <= x <= y <= b and Dx + Dx + 1 + ...... + Dy maximum. If the answer to take a plurality of sets lexicographically smallest set (i.e., x, y min).

 

Here is a little irrelevant nonsense (a little bit of interpreted code)

 

Because the two numbers to be output (x, y) obviously can not use a common return value, this selection to a data structure type as the return value, which is l, r is the required x, y

To be able to compare the size (lexicographical) wrote a  rainbow-like  operator overloading, friend functions. (You can also use pair)

But with the prefix and the sum [] to optimize.

 

It is noted that if overloaded operator can select or define a prefix and val,

However, if the pair, it must write overloaded operators (because there are not three amount).

 

Of course, you can also choose to manually write a comparison function

struct data{
    int l,r;
    long long val(){return sum[r]-sum[l-1];}
    friend bool operator > (data a,data b){
        return a.val()>b.val()||(a.val()==b.val()&&(a.l<b.l||(a.l==b.l&&a.r<b.r)));
    }
    friend bool operator < (data a,data b){
        return a.val()<b.val()||(a.val()==b.val()&&(a.l>b.l||(a.l==b.l&&a.r>b.r)));
    }
};

 

 

defmax data type is a max ....

data defmax(data a,data b){
    return a>b?a:b;
}

 

This will probably be written better? (You can use what type it ... woc it still compares other type?)

auto defmax(auto a,auto b){
  return  a>b?a:b;  
}

 

pushup:

Maxn relatively left, right, center

pre compare left, left + right

Similarly suf

void a pushup ( int RT) { 
        MAXN [RT] = defmax (defmax (MAXN [the LS], MAXN [the RS]), (Data) {SUF [the LS] .L, pre [the RS] .r});
         // left Middle and right 
        pre [RT] = defmax (pre [the LS], (Data) pre {[the LS] .L, pre [the RS] .r}); 
        SUF [RT] = defmax (SUF [the RS], (Data) SUF {[the LS] .L, SUF [the RS] .r});
         // Note here depends on the size of the interval length instead 
    }

 

build, is to build

 void build(int rt,int l,int r){
        if(l==r){
            pre[rt]=suf[rt]=Maxn[rt]=(data){l,r};
            return;
        }int mid=l+r>>1;
        build(LS,l,mid);
        build(RS,mid+1,r);
        pushup(rt); return;
    }

 

query

If it includes a direct return to the node maximum range

It is not within the range of about Analyzing (integer section)

In the middle of looking for a successor and predecessor find the right piece together the left, the left pure, pure and right contrast whichever is greater

  data query(int rt,int l,int r,int x,int y){
        if(x<=l&&y>=r)return Maxn[rt];
        int mid=l+r>>1;
        if(y<=mid) //左儿子
            return query(LS,l,mid,x,y);
        if(x>mid)  //右儿子
            return query(RS,mid+1,r,x,y);
        //在中间
        data a=defmax(query(LS,l,mid,x,y),query(RS,mid+1,r,x,y));
        data b=(data){asksuf(LS,l,mid,x,y).l,askpre(RS,mid+1,r,x,y).r};
        return defmax(a,b);
    }

 

Find precursors / successors (symmetric version)

Has been to find the right successor, the precursor to the left to find, just pieced together to ensure that the final

    asksuf Data ( int RT, int L, int R & lt, int X, int Y) { // find successor (r == y) in the left subtree 
        IF (SUF [RT] .L> = X) return SUF [RT ]; // this constant interval subsequent> subsequent son 
        int MID = L + R & lt >> . 1 ;
         IF (X> MID) return asksuf (the RS, MID + . 1 , R & lt, X, Y);
         return defmax ((Data) {asksuf (the LS, L, MID, X, Y) .L, R & lt}, SUF [the RS]); 
    } 
    Data askpre ( int RT, int L, int R & lt, int X, int y){
        if(pre[rt].r<=y)return pre[rt];
        int mid=l+r>>1;
        if(y<=mid)return askpre(LS,l,mid,x,y);
        return defmax((data){l,askpre(RS,mid+1,r,x,y).r},pre[LS]);
    }

 

 

Code

 

QAQ friend is not even highlighted that he added a eco-friendly green

/*uva1400*/
#include<iostream> #include<cmath> #include<algorithm> #include<cstdio> using namespace std; const int N=2e6+3; long long sum[N],a[N]; struct data{ int l,r; long long val(){return sum[r]-sum[l-1];} friend bool operator > (data a,data b){ return a.val()>b.val()||(a.val()==b.val()&&(a.l<b.l||(a.l==b.l&&a.r<b.r))); } friend bool operator < (data a,data b){ return a.val()<b.val()||(a.val()==b.val()&&(a.l>b.l||(a.l==b.l&&a.r>b.r))); } }; data defmax(data a,data b){ return a>b?a:b; } namespace Segment_Tree{ #define LS (rt<<1) #define RS (LS|1) data pre[N<<2],suf[N<<2],Maxn[N<<2]; //前驱 后继 最大子段和 void pushup(int rt){ Maxn[rt]=defmax (defmax (MAXN [the LS], MAXN [the RS]), (Data) {SUF [the LS] .L, pre [the RS] .r}); // left and right Middle pre [RT] = defmax (pre [ the LS], (Data) pre {[the LS] .L, pre [the RS] .r}); SUF [RT] = defmax (SUF [the RS], (Data) {SUF [the LS] .L, SUF [the RS] } .r); // Note here depends on the size of the interval length instead } void Build ( int RT, int L, int R & lt) { IF (L == R & lt) { pre [RT] = SUF [RT] = MAXN [RT] = (Data) {L, R & lt}; return ; } int MID = L + R & lt >> . 1 ; Build (the LS, L, MID); Build (the RS, MID + . 1 , R & lt); a pushup (RT); return ; } Data asksuf ( int RT, int L, int R & lt, int X, int Y) { // find successor (r == in the left subtree Y) IF (SUF [RT] .L> = X) return SUF [RT]; // this constant interval subsequent> subsequent son int MID = L + R & lt >> . 1 ; IF (X> MID) return asksuf (the RS, + MID . 1 , R & lt, X, Y); return defmax ((Data) {asksuf (the LS, L, MID, X, Y) .L, R & lt}, SUF [the RS]); } Data askpre ( int RT,int l,int r,int x,int y){ if(pre[rt].r<=y)return pre[rt]; int mid=l+r>>1; if(y<=mid)return askpre(LS,l,mid,x,y); return defmax((data){l,askpre(RS,mid+1,r,x,y).r},pre[LS]); } data query(int rt,int l,int r,int x,int y){ if(x<=l&&y>=r)return Maxn[rt]; int mid=l+r>>1; if(y<=mid) //左儿子 return query(LS,l,mid,x,y); if(x>mid) //右儿子 return query(RS,mid+1,r,x,y); //在中间 data a=defmax(query(LS,l,mid,x,y),query(RS,mid+1,r,x,y)); data b=(data){asksuf(LS,l,mid,x,y).l,askpre(RS,mid+1,r,x,y).r}; return defmax(a,b); } } using namespace Segment_Tree; int main(){ int n,m,x,y,Case=0 ; Data ANS; the while (Scanf ( " % D% D " , & n-, & m) =! The EOF) { the printf ( " Case% D: \ n- " , ++ Case); for ( int I = . 1 ; I < n-=; ++ I) { Scanf ( " % LLD " , & a [I]); SUM [I] = a [I] + SUM [I- . 1 ]; // SUM overwrites previous, may not be initialized } Build ( . 1 , . 1 , n-); the while (M-- ) { Scanf ("%d%d",&x,&y); ans=query(1,1,n,x,y); printf("%d %d\n",ans.l,ans.r); } } return 0; }

 

Guess you like

Origin www.cnblogs.com/lsy263/p/11229407.html