zoukankan      html  css  js  c++  java
  • [ZJOI2006]书架(二分+树状数组)

    这题90%以上的人做法为裸的平衡树,实际上根本没必要还常数大,最好的方法是二分+树状数组。具体做法是,开3倍内存,初始把中间n位赋值为1。对于每个操作:1&2、删除该位,将其丢在头/尾(开三倍内存的原因)。3、插入时直接二分查询第ask(x)+y位,换一下即可。4、直接查询。5、二分查询。复杂度O(nlog2n)

    #include<bits/stdc++.h>
    using namespace std;
    const int N=240010;
    int n,m,a[N],id[N],c[N];
    void add(int x,int v){while(x<=2*m+n)c[x]+=v,x+=x&-x;}
    int ask(int x){int ret=0;while(x)ret+=c[x],x-=x&-x;return ret;}
    int find(int x)
    {
        int l=1,r=2*m+n,mid,pos=2*m+n;
        while(l<=r)
        {
            mid=l+r>>1;
            if(ask(mid)>=x)pos=mid,r=mid-1;
            else l=mid+1;
        }
        return pos;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1,x;i<=n;i++)scanf("%d",&a[i+m]),id[a[i+m]]=i+m,add(i+m,1);
        for(int i=1;i<=m;i++)
        {
            char str[10];int x,y,t,pos,tmp;
            scanf("%s%d",str,&x);
            if(str[0]=='T')pos=find(1),add(id[x],-1),add(pos-1,1),id[x]=pos-1,a[id[x]]=x;
            if(str[0]=='B')pos=find(n),add(id[x],-1),add(pos+1,1),id[x]=pos+1,a[id[x]]=x;
            if(str[0]=='I')
            {
                scanf("%d",&y);
                if(!y)continue;
                pos=find(ask(id[x])+y),tmp=a[pos];
                swap(a[pos],a[id[x]]),swap(id[x],id[tmp]);
            }
            if(str[0]=='A')printf("%d
    ",ask(id[x])-1);
            if(str[0]=='Q')printf("%d
    ",a[find(x)]);
        }
    }
    View Code
  • 相关阅读:
    备忘--ruby相关
    Redhat下安装ruby
    ubuntu装机相关设定及问题系列(6)
    ubuntu装机相关设定及问题系列(5)
    备忘--ubuntu装机历程
    备忘--ubuntu10下安装ruby和cucumber
    jQuery--checkbox全选/取消全选
    经常用的Jquery图片轮转
    JavaScript js 兼容浏览器问题 兼容Fire
    net页面生命周期
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/10911340.html
Copyright © 2011-2022 走看看