首页 > 其他 > 详细

spoj8406

时间:2017-11-25 10:19:09      阅读:274      评论:0      收藏:0      [点我收藏+]

题解:

二分+树状数组

记录以下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); 
         } 
     }
}

 

spoj8406

原文:http://www.cnblogs.com/xuanyiming/p/7894531.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!