1. 程式人生 > >JZOJ-senior-5933. 【NOIP2018模擬10.27】百鴿籠

JZOJ-senior-5933. 【NOIP2018模擬10.27】百鴿籠

Time Limits: 2000 ms Memory Limits: 262144 KB

Description

在這裡插入圖片描述
在這裡插入圖片描述

Input

從檔案 pigeon.in 中讀入資料。
輸入第一行包含兩個正整數 n, m ,分別表示初始鴿籠數與操作個數。
第二行包含 n 個正整數,第 i 個數表示從左往右第 i 個初始鴿籠中鴿子的咕咕能力值 vi 。
接下去 m 行每行表示一個操作。操作輸入格式見題面描述。

Output

輸出到檔案 pigeon.out 中。
輸出包含若干行,每行表示一個相應的 3 操作的答案。

Sample Input

6 8
2 7 4 3 5 9
3 2 5 3
1
2 4
3 1 4 2
2 6
3 1 7 5
1
3 3 6 4

Sample Output

5
4
6
9

在這裡插入圖片描述

Data Constraint

在這裡插入圖片描述
題目更正:vi值域小於等於1e9。

Solution

  • 在前端加入刪除,那就反過來啊
  • 動態查詢區間第K小,那就上主席樹啊
  • 真是簡單又自然,難得在比賽場上我這種菜雞能切掉一題

Code

#include<algorithm>
#include<cstdio>
#include<cctype>

#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fd(i,a,b) for(int i=a;i>=b;--i)
#define P(c) putchar(c) using namespace std; const int N=4e5+5,M=128e5+5,MX=1e9; int n,m,t,v,L,R,K,tot,cnt; int a[N],rt[N]; struct tree{int l,r,s;}tr[M]; inline void read(int &n) { int x=0,w=0; char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<3)+(x<<
1)+(ch^48),ch=getchar(); n=w?-x:x; } inline void write(int x) { if(x<0) x=-x,putchar('-'); if(x>9) write(x/10); putchar(x%10+'0'); } void ins(int x,int l,int r,int p) { if(l==r) return; int mid=(l+r)>>1; if(p<=mid) { int y=tr[x].l; tr[++tot]=(tree){tr[y].l,tr[y].r,tr[y].s+1}; tr[x].l=tot,ins(tr[x].l,l,mid,p); } else { int y=tr[x].r; tr[++tot]=(tree){tr[y].l,tr[y].r,tr[y].s+1}; tr[x].r=tot,ins(tr[x].r,mid+1,r,p); } } void ask(int x,int y,int l,int r,int p) { if(l==r) {write(l),P('\n'); return;} int mid=(l+r)>>1; int lx=tr[x].l,ly=tr[y].l; int rx=tr[x].r,ry=tr[y].r; if(tr[ly].s-tr[lx].s>=p) ask(lx,ly,l,mid,p); else ask(rx,ry,mid+1,r,p-(tr[ly].s-tr[lx].s)); } int main() { freopen("pigeon.in","r",stdin); freopen("pigeon.out","w",stdout); read(n),read(m),tot=cnt=n; fo(i,1,n) read(a[i]); fo(i,1,n/2) swap(a[i],a[n-i+1]); fo(i,1,n) { tr[i]=(tree){tr[i-1].l,tr[i-1].r,tr[i-1].s+1}; rt[i]=i,ins(i,1,MX,a[i]); } fo(i,1,m) { read(t); if(t==1) --cnt; if(t==2) { read(v); int lst=rt[cnt]; rt[++cnt]=++tot; tr[tot]=(tree){tr[lst].l,tr[lst].r,tr[lst].s+1}; ins(tot,1,MX,v); } if(t==3) { read(L),read(R),read(K); int opl=cnt-R+1,opr=cnt-L+1; ask(rt[opl-1],rt[opr],1,MX,K); } } }