Hướng dẫn giải của Hợp tan


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
#include<bits/stdc++.h>
using namespace std;
#define all(fl) fl.begin(),fl.end()
#define pb push_back
#define fi first
#define se second
#define for1(i,j,k) for(int i=j;i<=k;i++)
#define for2(i,j,k) for(int i=j;i>=k;i--)
#define for3(i,j,k,l) for(int i=j;i<=k;i+=l)
#define lb lower_bound
#define ub upper_bound
#define sz(a) (int)a.size()
#define pii pair<int,int>
#define pli pair<long long,int>
#define gcd __gcd
#define lcm(x,y) x*y/__gcd(x,y)
const int maxn=2e5+9;
int a[maxn],st[maxn<<2],bit[maxn],n,q;
pii b[maxn];
void build(int id,int l,int r){
if (l==r){
    st[id]=a[l];
    return;
}
int mid=(l+r)>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
st[id]=max(st[id<<1],st[id<<1|1]);
}
int get(int id,int l,int r,int u,int v){
if (l>v||r<u||u>v)return 0;
if (u<=l&&r<=v)return st[id];
int mid=(l+r)>>1;
return max(get(id<<1,l,mid,u,v),get(id<<1|1,mid+1,r,u,v));
}
void add(int pos,int val){
if (pos==0)return;
for (;pos<=n;pos+=(pos-(pos&(pos-1))))bit[pos]+=val;
}
int get(int pos){
int sum=0;
for(;pos>=1;pos-=(pos-(pos&(pos-1))))sum+=bit[pos];
return sum;
}
int ps[maxn];
signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    //freopen("temp.INP","r",stdin);
    //freopen("temp.OUT","w",stdout);
    cin>>n>>q;
    for1(i,1,n)cin>>a[i],ps[a[i]]=i;
    int start=0,mx=0;
    for1(i,1,n){
    if (mx<a[i]){
    mx=a[i];
    b[a[start]]={start,i-1};
    add(a[start],i-start);
    start=i;
    }
    }
    build(1,1,n);
    b[a[start]]={start,n};
    add(a[start],n-start+1);
    for1(i,1,q){
    int type,pos;
    cin>>type>>pos;
    if (type==1){
    int l=1,r=n,ans=0;
    while (l<=r){
    int mid=(l+r)/2;
    if (get(mid)>=pos){
    ans=mid;
    r=mid-1;
    }
    else l=mid+1;
    }
    pos-=get(ans-1);
    cout<<a[b[ans].fi+pos-1]<<'\n';
    }
    else {
    pos++;
    int l=1,r=n,ans=0;
    while (l<=r){
    int mid=(l+r)/2;
    if (get(mid)>=pos){
    ans=mid;
    r=mid-1;
    }
    else l=mid+1;
    }
    pos-=get(ans-1);
    if (pos==1)continue;
    l=b[ans].fi+pos-1,r=b[ans].se;
    b[ans].se=l-1;
    add(ans,-(r-l+1));
    while (l<=r){
    int mx=get(1,1,n,l,r);
    b[mx]={ps[mx],r};
    add(mx,r-ps[mx]+1);
    r=ps[mx]-1;
    }
    }
    }
}

Đang tải...