【JZOJ A組】百鴿籠
阿新 • • 發佈:2018-11-01
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。
思路
把序列倒過來,建一棵線段樹即可
程式碼
#include<cstdio> #include<iostream> #include<cstring> #define maxn 400077 #define inf 1000000000 using namespace std; int n,m,ans,cnt,k[maxn],v[maxn]; struct T{int v,l,r;}tr[maxn*31]; void add(int &d,int l,int r,int x) { tr[++cnt]=tr[d],tr[d=cnt].v++; if (l==r) return; int mid=(l+r)>>1; if (x<=mid) add(tr[d].l,l,mid,x); else add(tr[d].r,mid+1,r,x); } void query(int l,int r,int st,int ed,int x) { if (st==ed) { ans=st; return; } int mid=(st+ed)>>1; if (x<=tr[tr[l].l].v-tr[tr[r].l].v) query(tr[l].l,tr[r].l,st,mid,x); else query(tr[l].r,tr[r].r,mid+1,ed,x-tr[tr[l].l].v+tr[tr[r].l].v); } int main() { freopen("pigeon.in","r",stdin),freopen("pigeon.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) scanf("%d",&v[i]); for(int i=1; i<=n/2; i++) swap(v[i],v[n-i+1]); for(int i=1; i<=n; i++) k[i]=k[i-1],add(k[i],0,inf,v[i]); for(int i=1,num,x,l,r; i<=m; i++) { scanf("%d",&num); if (num==1) n--; if (num==2) scanf("%d",&x),k[++n]=k[n-1],add(k[n],0,inf,x); if (num==3) { scanf("%d%d%d",&l,&r,&x),swap(l,r); l=n-l+1,r=n-r+1,query(k[r],k[l-1],0,inf,x); printf("%d\n",ans); } } }