萌新求助30分(我给您跪下了)

P2839 [国家集训队] middle

cxlian25 @ 2024-01-30 16:42:49

//#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<unordered_map>
#include<cmath>
#include<queue>
#include<map>
#include<cstring>
#include<vector>
#include<set>
#define ll long long
#define lx (x<<1)
//#define endl '\n'
#define rx (x<<1|1)
#define db double
#define pb push_back
#define mp make_pair
#define pa pair<int,int>
#define mid ((l+r)>>1)
#define mem(a) memset(a,0,sizeof(a))
#define memf(a) memset(a,127,sizeof(a))//浮点,int数最大 
#define memm(a) memset(a,0x3f,sizeof(a))//1e9
#define memn(a) memset(a,0xcf,sizeof(a))//int最小 
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define ct(a) (__builtin_popcount(a))
#define lowbit(i) (i&(-i))
using namespace std;
const int N=1e5+7,M=1e6,p=1000000007;
const double eps=1e-9,pi=acos(-1.0);
int tt;
int n,m,cnt=0,len=0;
int a[N],b[N],id=0,q[9];
struct tree{
    int l,r;
    int mxl,mxr,sum;
}st[N<<5];  
vector<int>v[N];
int root[N];
int build(int l,int r){
    int now=++cnt;
    if(l<r){
        st[now].l=build(l,mid);
        st[now].r=build(mid+1,r);
    }
    else{
        st[now].mxl=st[now].mxr=1;
        st[now].sum=1;
        return now;
    }
    st[now].sum=st[st[now].l].sum+st[st[now].r].sum;
    st[now].mxl=max(st[st[now].l].mxl,st[st[now].l].sum+st[st[now].r].mxl);
    st[now].mxr=max(st[st[now].r].mxr,st[st[now].r].sum+st[st[now].l].mxr);
    return now;
}
void add(int pre,int &now,int l,int r,int x){
    if(!now)now=++cnt;
    if(l==r){
        st[now].mxl=st[now].mxr=-1;
        st[now].sum=-1;
        return;
    }
    if(x<=mid)add(st[pre].l,st[now].l,l,mid,x),st[now].r=st[pre].r;
    else add(st[pre].r,st[now].r,mid+1,r,x),st[now].l=st[pre].l;
    st[now].sum=st[st[now].l].sum+st[st[now].r].sum;
    st[now].mxl=max(st[st[now].l].mxl,st[st[now].l].sum+st[st[now].r].mxl);
    st[now].mxr=max(st[st[now].r].mxr,st[st[now].r].sum+st[st[now].l].mxr);
}
tree qry1(int x,int l,int r,int sl,int sr){
    tree now;now.sum=-10000000;
    if(sr<l||sl>r)return now;
    if(sl<=l&&sr>=r)return st[x];
    tree left=qry1(st[x].l,l,mid,sl,sr);
    tree right=qry1(st[x].r,mid+1,r,sl,sr);
    if(left.sum==-10000000&&right.sum==-10000000)return now;
    if(left.sum==-10000000)return right;
    if(right.sum==-10000000)return left;
    now.mxl=max(left.mxl,left.sum+right.mxl);
    now.mxr=max(right.mxr,right.sum+left.mxr);
    now.sum=left.sum+right.sum;
    return now;
}
bool check(int w){
    int sum=0;
    if(q[2]+1<=q[3]-1)sum=sum+qry1(root[w],1,len,q[2]+1,q[3]-1).sum;
    sum=sum+qry1(root[w],1,len,q[1],q[2]).mxr;
    sum=sum+qry1(root[w],1,len,q[3],q[4]).mxl;
    return sum>=0;
}
void solve(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        b[i]=a[i];
    }
    sort(b+1,b+1+n);
    len=n;
    len=unique(b+1,b+1+n)-b-1;
    for(int i=1;i<=n;i++){
        a[i]=lower_bound(b+1,b+1+len,a[i])-b;
        v[a[i]].pb(i);
    }
    root[1]=build(1,len);
    for(int i=2;i<=n;i++){
        root[i]=root[i-1];
        for(auto x:v[i-1]){
            if(root[i]==root[i-1])root[i]=0;
            add(root[i-1],root[i],1,len,x);
        }
    }
    scanf("%d",&m);
    int tmp=0;
    while(m--){
        for(int i=1;i<=4;i++){
            scanf("%d",&q[i]);
            q[i]=(q[i]+tmp)%n+1;
        }
        sort(q+1,q+1+4);
        int l=1,r=len;
        while(l<=r){
            if(check(mid))l=mid+1;
            else r=mid-1;
        }
        tmp=b[r];
        printf("%d\n",tmp);
    }
}
/*
300000 2 30
*/
signed main(){
//  IOS;
//  cin>>tt;
//  scanf("%d",&tt);
    tt=1;
    while(tt--){
        solve();
//      puts("");
    }
    return 0;
}
/*
1
1 2 3 4 5
1 2 2 3 3
*/

by cxlian25 @ 2024-01-30 18:29:29

@cxlian25 破案了,不能离散化,原因是可持久化的是线段树而不是权值线段树


|