• 【bzoj3295】[Cqoi2011]动态逆序对 树套树 线段树套替罪羊树


    这个东西,关于某个数的逆序对数为在他之前比他大的在他之后比他小的数的数目的和,所以删除之前先把这个减去就好了

    人傻自带超大常数,中间由于内存池开小了所以运行错误。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define MAXN 100010
    using namespace std;
    typedef long long LL;
    typedef double D;
    const D a=0.756;
    LL ans;
    struct ScapeGoat_Tree
    {
        ScapeGoat_Tree *ch[2];
        int key,size,cover,ex;
        bool bad()
        {
          return cover*a+5<ch[0]->cover||cover*a+5<ch[1]->cover;
        }
        void pushup()
        {
           size=ch[0]->size+ch[1]->size+ex;
           cover=ch[0]->cover+ch[1]->cover+1;
        }
    }*null,*stack[(MAXN<<5)+5],pool[(MAXN<<5)+5],*lst[(MAXN<<4)+5];
    int  top,len;
    inline void Init()
    {
        null=pool;
        null->ch[1]=null->ch[0]=null;
        null->key=null->size=null->cover=null->ex=0;
        for(int  i=1;i<(MAXN<<5);i++)stack[++top]=pool+i;
    }
    inline ScapeGoat_Tree *New(int  key)
    {
        ScapeGoat_Tree *p=stack[top--];
        p->ch[1]=p->ch[0]=null;
        p->key=key;
        p->size=p->ex=p->cover=1;
        return p;
    }
    struct Tree
    {
        Tree *ch[2];
        int  mid,l,r;
        ScapeGoat_Tree *root;
        Tree(){ch[1]=ch[0]=NULL;mid=l=r=0;root=null;}
        void* operator new(size_t size);
    }*root,*C,*mempool;
    void* Tree :: operator new(size_t size)
    {
        if(C==mempool)
        {
           C=new Tree[(1<<15)+5];
           mempool=C+(1<<15)+5;
        }
        C->root=null; 
        return C++;
    }
    void travel(ScapeGoat_Tree *p)
    {
        if(p==null)return;
        travel(p->ch[0]);
        if(p->ex)lst[++len]=p;
        else stack[++top]=p;
        travel(p->ch[1]);
    }
    ScapeGoat_Tree *divide(int  l,int  r)
    {
        if(l>r)return null;
        int  mid=(l+r)>>1;
        lst[mid]->ch[0]=divide(l,mid-1);
        lst[mid]->ch[1]=divide(mid+1,r);
        lst[mid]->pushup();
        return lst[mid];
    }
    inline void rebuild(ScapeGoat_Tree *&p)
    {
        len=0;
        travel(p);
        p=divide(1,len);
    }
    ScapeGoat_Tree **insert(ScapeGoat_Tree *&p,int  key)
    {
        if(p==null )
        {
          p=New(key);
          return &null;
        }
        p->size++;
        p->cover++;
        ScapeGoat_Tree **ret=insert(p->ch[p->key<=key],key);
        if(p->bad())ret=&p;
        return ret;
    }
    inline void Insert(ScapeGoat_Tree *&Root,int  key)
    {
        ScapeGoat_Tree **p=insert(Root,key);
        if(*p!=null )rebuild(*p);
    }
    inline int  Rank_Max(ScapeGoat_Tree *Root,int  key)
    {
        ScapeGoat_Tree *now=Root;
        int  ret=0;
        while(now!=null )
         if(now->key<=key)
          now=now->ch[1];
         else
          ret+=now->ch[1]->size+now->ex,now=now->ch[0];
        return ret;
    }
    inline int  Rank_Min(ScapeGoat_Tree *Root,int key)
    {
        ScapeGoat_Tree *now=Root;
        int  ret=0;
        while(now!=null )
         if(now->key>=key)
          now=now->ch[0];
         else
          ret+=now->ch[0]->size+now->ex,now=now->ch[1];
        return ret;
    }
    void del(ScapeGoat_Tree *p,int k)
    {
        p->size--;
        if(p->ex&&p->ch[0]->size+1==k)
        {
          p->ex=0;
          return;
        }
        if(p->ch[0]->size>=k) del(p->ch[0],k);
        else del(p->ch[1],k-p->ch[0]->size-p->ex);
    }
    inline void Del(ScapeGoat_Tree *&Root,int  key)
    {
        del(Root,Rank_Min(Root,key)+1);
        if(Root->size<Root->cover*a)rebuild(Root);
    }
    int  n,m,pos[MAXN];
    void build(Tree *p)
    {
         p->mid=(p->l+p->r)>>1;
         if(p->l==p->r)return;
         p->ch[0]=new Tree;
         p->ch[0]->l=p->l;
         p->ch[0]->r=p->mid;
         p->ch[1]=new Tree;
         p->ch[1]->l=p->mid+1;
         p->ch[1]->r=p->r;
         build(p->ch[0]);
         build(p->ch[1]);
    }
    void Ins(Tree *p,int  key,int  aim)
    {
         Insert(p->root,key);
         if(p->l==p->r)return;
         Ins(p->ch[p->mid<aim],key,aim);
    }
    int  query_Max(int  l,int  r,int  key,Tree *p)
    {
         if(l<=p->l&&p->r<=r)
            return Rank_Max(p->root,key);
         int  tmp=0;
         if(l<=p->mid)tmp+=query_Max(l,r,key,p->ch[0]);
         if(p->mid<r)tmp+=query_Max(l,r,key,p->ch[1]);
         return tmp;
    }
    int  query_Min(int  l,int  r,int  key,Tree *p)
    {
         if(l<=p->l&&p->r<=r)
          return Rank_Min(p->root,key);
         int  tmp=0;
         if(l<=p->mid)tmp+=query_Min(l,r,key,p->ch[0]);
         if(p->mid<r)tmp+=query_Min(l,r,key,p->ch[1]);
         return tmp;
    }
    void Delete(Tree *p,int  key,int  aim)
    {
         Del(p->root,key);
         if(p->l==p->r)return;
         Delete(p->ch[p->mid<aim],key,aim);
    }
    int main()
    {
        //freopen("inverse.in","r",stdin);
        //freopen("inverse.out","w",stdout);
        Init();
        scanf("%d%d",&n,&m);
        root=new Tree;
        root->l=1;
        root->r=n;
        build(root);
        for(int  i=1;i<=n;i++)
        {
          int x;
          scanf("%d",&x);
          pos[x]=i;
          Ins(root,x,i);
          if(i!=1)ans+=query_Max(1,i-1,x,root);
        }
        for(int  i=1;i<=m;i++)
        {
          printf("%lld
    ",ans);
          int  x;
          scanf("%d",&x);
          if(pos[x]!=1) ans-=query_Max(1,pos[x]-1,x,root);
          if(pos[x]!=n) ans-=query_Min(pos[x]+1,n,x,root);
          Delete(root,x,pos[x]);
        }
        return 0;
    }
    苟利国家生死以, 岂因祸福避趋之。
  • 相关阅读:
    结构型模式代理&适配器
    创建型模式单例&工厂&建造者&原型
    结构型模式装饰者&桥接&门面
    python中列表(list)的使用
    Win2003 域控制器设置和客户端安装
    Python下冒泡排序的实现
    乔布斯在斯坦福大学毕业典礼上的演讲
    字符串替换
    统计文件中某一字符串出现的次数
    [用户 'sa' 登录失败。原因: 该帐户被禁用]的解决方案
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7001884.html
Copyright © 2020-2023  润新知