题解:
二分+树状数组
记录以下i在当前拍第几
代码:
#include<bits/stdc++.h> using namespace std; const int N=200005; int a[N],f1[N],f2[N],n,m,x,y,num[N]; int js(int x) { int ans=0; for (;x;x-=x&-x)ans+=num[x]; return ans; } void inster(int x,int y) { for (;x<=n;x+=x&-x)num[x]+=y; } int cmp(int x,int y) { return a[x]<a[y]; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++)scanf("%d",&a[i]),f1[i]=f2[i]=i; sort(f1+1,f1+n+1,cmp); for (int i=1;i<=n;i++)f2[f1[i]]=i; for (int i=1;i<=n;i++)inster(i,a[f1[i]]-a[f1[i-1]]); while (m--) { scanf("%d%d",&x,&y); if (x==2) { if (js(n)<y){puts("0");continue;} int l=1,r=n; while (l<r) { int mid=(l+r)/2; if (y>js(mid))l=mid+1; else r=mid; } printf("%d\n",n-l+1); } if (x==3) { if (js(n)<y)continue; int l=1,r=n; while (l<r) { int mid=(l+r)/2; if (y>js(mid))l=mid+1; else r=mid; } inster(l,-1); } if (x==1) { int l=1,r=n,k=js(f2[y]); while (l<r) { int mid=(l+r+1)/2; if (k<js(mid))r=mid-1; else l=mid; } swap(f1[f2[y]],f1[l]); swap(f2[f1[f2[y]]],f2[f1[l]]); inster(l,1); inster(l+1,-1); } } }
原文:http://www.cnblogs.com/xuanyiming/p/7894531.html