BZOJ2653 middle (只是存个板子,什么都没写)

 比较皮的一点是,本题我们先按权值排序,建主席树,然后每个线段树是按下标建的,/

#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<vector>
#include<iostream>
#define ll long long
#define re register
#define inf 0x3f3f3f3f
#define inl inline
#define sqr(x) (x*x)
//#define eps 1e-8
#define debug printf("debug\n");
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#pragma GCC optimize (2)
//#pragma G++ optimize (2)
using namespace std;
//const ll mod;
const ll MAXN=2e4+10;
inl ll read() {
    re ll x = 0; re int f = 1;
    char ch = getchar();
    while(ch<'0'||ch>'9') { if(ch== '-' ) f = -1; ch = getchar(); }
    while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x * f;
}
inl char readc() {
    char ch=getchar();
    while(('z'<ch||ch<'a')&&('Z'<ch||ch<'A')) ch=getchar();
    return ch;
}
inl void write(re ll x){
    if(x>=10)write(x/10);
    putchar(x%10+'0');
}
inl void writeln(re ll x){
    if(x<0) {x=-x;putchar('-');}
    write(x); puts("");
}
inl ll gcd(re ll x,re ll y){while(y^=x^=y^=x%=y);return x;}
inl void FR() {
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
}
inl void FC() {
    fclose(stdin);
    fclose(stdout);
}
struct Node {
    ll son[2],cnt,lmax,rmax,x;
    void clear() {
        son[0]=son[1]=cnt=lmax=rmax=x=0;
    }
}Tree[MAXN<<5];
struct P {
    ll id,x;
}s[MAXN];
ll T_cnt,ans;
bool cmp(P a,P b) {return a.x<b.x;}
inl void pushup(ll x,ll y,ll z) {
    Tree[x].lmax=max(Tree[y].lmax,Tree[y].cnt+Tree[z].lmax);
    Tree[x].rmax=max(Tree[z].rmax,Tree[z].cnt+Tree[y].rmax);
    Tree[x].cnt=Tree[z].cnt+Tree[y].cnt;
} 
ll build(ll l,ll r) {
    re ll t=T_cnt++;
    if(l==r) {
        Tree[t].x=Tree[t].lmax=Tree[t].rmax=Tree[t].cnt=1;
        return t;
    }
    re ll mid=(l+r)>>1;
    Tree[t].son[0]=build(l,mid);Tree[t].son[1]=build(mid+1,r);
    pushup(t,Tree[t].son[0],Tree[t].son[1]);
    return t;
}
ll insert(ll pre,ll l,ll r,ll k) {
    re ll t=++T_cnt;
    if(l==r) {
        Tree[t].cnt=Tree[t].x=-1;
        Tree[t].lmax=Tree[t].rmax=0;
        return t;
    }
    re ll mid=(l+r)>>1;
    Tree[t]=Tree[pre];
    if(k<=mid) Tree[t].son[0]=insert(Tree[pre].son[0],l,mid,k);
    else Tree[t].son[1]=insert(Tree[pre].son[1],mid+1,r,k);
    pushup(t,Tree[t].son[0],Tree[t].son[1]);
    return t;
}
void query(ll x,ll l,ll r,ll L,ll R) {
    if(L<=l&&r<=R) {pushup(ans,ans,x);return ;}
    if(l>R||r<L||R<L) return ;
    re ll mid=(l+r)>>1;
    query(Tree[x].son[0],l,mid,L,R);
    query(Tree[x].son[1],mid+1,r,L,R);
}
ll n,q[8],root[MAXN];
bool check(ll x,ll a,ll b,ll c,ll d) {
    ll sum=0;ans=0;
    Tree[ans].clear();query(root[x],1,n,a,b-1);sum+=Tree[ans].rmax;
    Tree[ans].clear();query(root[x],1,n,b,c);sum+=Tree[ans].cnt;
    Tree[ans].clear();query(root[x],1,n,c+1,d);sum+=Tree[ans].lmax;
    return sum>=0;
}
int main() {
//  FR(); 
    n=read();
    for(re ll i=1;i<=n;i++) s[i].x=read(),s[i].id=i;
    sort(s+1,s+n+1,cmp);//权值排序 
    root[0]=build(1,n);
    for(re ll i=1;i<=n;i++) {root[i]=insert(root[i-1],1,n,s[i].id);}
    re ll Q=read(),lastans=0;
    for(re ll i=1;i<=Q;i++) {
        re ll a=read(),b=read(),c=read(),d=read();
        q[0]=(a+lastans)%n+1,q[1]=(b+lastans)%n+1;//1开头我习惯一点 
        q[2]=(c+lastans)%n+1,q[3]=(d+lastans)%n+1;//不改也行 
        sort(q,q+4);
        a=q[0],b=q[1],c=q[2],d=q[3];
        ll l=0,r=n;
        while(l!=r) {
            re ll mid=(l+r)>>1;
            if(check(mid+1,a,b,c,d)) l=mid+1;
            else r=mid;
        }//二分找第几大的 
        lastans=s[l+1].x;
        writeln(lastans);
    }
//  FC();
    return 0;
}

[手动滑稽]

猜你喜欢

转载自www.cnblogs.com/20020723YJX/p/9384784.html