JZOJ-senior-5933. 【NOIP2018模擬10.27】百鴿籠
阿新 • • 發佈:2018-11-08
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);
}
}
}