[National Team] middle explanations

Questions face Portal

This question we first think of a common approach to the median:

Bipartite enumeration answer ans, ans number becomes greater than 1, it becomes smaller than 1; and if the interval is greater than 1, then the median is larger than the enumerated answer, or smaller;

But this question is not to determine the interval, are we going to enumerate n * n? Certainly not;

Observe nature, we found that for the interval [b, c], we certainly want to choose, then put that interval and added to in the answer;

Because the title says median selected as large as possible, based on two sharing nature, range and greater, the greater the median; therefore we selected intervals and to maximum;

That is, we have to select rmax [a, b] and lmax [c, d];

In summary, for each determined half, if rmax [a, b] + lmax [c, d] + sum (b, c)> = 0, then the median is larger than the current enumeration answer, and then change the binary condition L = mid + 1;

We can answer for each half of the range into 01 sequences, using the tree line can be done nlogn;

But this place explosive space complexity, I think of our good friends: Chairman of the tree;

Found: If half the answer becomes ans ans + 1, then ans + 1 corresponding to the line of the tree in relation to ans ans + segment tree is only equal to the weight of 1 point some changes need to build more than clear that each of amortized only down tree node (logN);

So happy with $ n \ log ^ {2} n $ time complexity of this question out AC;

#include <bits/stdc++.h>
#define inc(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;
int aa[20010],lisan;
int in[10],root[20010];
class node2{
    public:
    int x,id;
}query[200010];
bool cmp(node2 x,node2 y){
    return x.x<y.x;
}
class node{
    public:
    int lson,rson;
    int sum,lmax,rmax;
    #define mid (l+r)/2
}tree[2000010];
int tot;
void updata(int k){
    tree[k].sum=tree[tree[k].lson].sum+tree[tree[k].rson].sum;
    tree[k].lmax=max(tree[tree[k].lson].lmax,tree[tree[k].rson].lmax+tree[tree[k].lson].sum);
    tree[k].rmax=max(tree[tree[k].rson].rmax,tree[tree[k].lson].rmax+tree[tree[k].rson].sum);
}
int build(int l,int r){
    int root=++tot;
    if(l==r){
        tree[root].sum=tree[root].lmax=tree[root].rmax=1;
        return root;
    }
    tree[root].lson=build(l,mid);
    tree[root].rson=build(mid+1,r);
    updata(root); return root;
}
void add(int &now,int pre,int l,int r,int goal,int value){
    now=++tot;
    tree[now]=tree[pre];
    if(l==r){
        tree[now].lmax=tree[now].rmax=tree[now].sum=value;
        return;
    }
    if(goal<=mid){
        add(tree[now].lson,tree[pre].lson,l,mid,goal,value);
    }
    else{
        add(tree[now].rson,tree[pre].rson,mid+1,r,goal,value);
    }
    updata(now);
}
int querysum(int now,int l,int r,int x,int y){
    if(x>r||y<l) return 0;
    if(x<=l&&r<=y) return tree[now].sum;
    return (querysum(tree[now].lson,l,mid,x,y)+querysum(tree[now].rson,mid+1,r,x,y));
}
int querylmax(int now,int l,int r,int x,int y){
    if(x>r||y<l) return -99999999;
    if(x<=l&&r<=y) return tree[now].lmax;
    return max(querylmax(tree[now].lson,l,mid,x,y),querylmax(tree[now].rson,mid+1,r,x,y)+querysum(tree[now].lson,l,mid,x,y));
}
int queryrmax(int now,int l,int r,int x,int y){
    if(x>r||y<l) return -99999999;
    if(x<=l&&r<=y) return tree[now].rmax;
    int tmp1=queryrmax(tree[now].rson,mid+1,r,x,y),tmp2=queryrmax(tree[now].lson,l,mid,x,y)+querysum(tree[now].rson,mid+1,r,x,y);
    return max(tmp1,tmp2);
}
int n; 
bool check(int now,int a,int b,int c,int d){
    int sum=0;
    if(b+1<=c-1) sum+=querysum(root[now],1,n,b+1,c-1);
    sum+=queryrmax(root[now],1,n,a,b);
    sum+=querylmax(root[now],1,n,c,d);
    if(sum>=0) return 1;
    else return 0;
}
int main()
{
    scanf("%d",&n);
    inc(i,1,n){
        scanf("%d",&query[i].x);
        query[i].id=i;
    }
    sort(query+1,query+1+n,cmp);
    root[1]=build(1,n);
    inc(i,2,n+1){
        add(root[i],root[i-1],1,n,query[i-1].id,-1);
    }
    int q; scanf("%d",&q);
    int ans=0;
    inc(i,1,q){
        scanf("%d%d%d%d",&in[0],&in[1],&in[2],&in[3]);
        in[0]=(in[0]+ans)%n; in[1]=(in[1]+ans)%n; in[2]=(in[2]+ans)%n; in[3]=(in[3]+ans)%n;
        sort(in,in+4);
        int L=1,R=n;
        while(L<=R){
            int midd=(L+R)/2;
            if(check(midd,in[0]+1,in[1]+1,in[2]+1,in[3]+1)){
                L = midd + 1 ; years = midd; 
            } 
            Else { 
                R = midd- 1 ; 
            } 
        } 
        Years = query [years] .x; 
        printf ( " % d \ n " , year); 
    } 
} 
/ * 
5 
170 337 785 
271 451 044 
22.43028 million 
969056313 
206452321 
3 
3 1 0 2 
2 3 1 4 
3 1 4 0 
* /

Guess you like

Origin www.cnblogs.com/kamimxr/p/12108639.html