• 【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;
    }
    苟利国家生死以, 岂因祸福避趋之。
  • 相关阅读:
    Ajax | Form 上传图片文件
    .NET Core 上传图片到七牛云
    限制input输入框只能输入 数字
    MySql操作命令创建学生管理系统
    大数据之kafka-05.讲聊聊Kafka的版本号
    大数据之kafka-02.搞定kafka专业术语
    消息队列的作用以及kafka和activemq的对比
    .Net Core 3.1迁移整理
    RabbitMQ的使用
    .NET Framework 项目多环境下配置文件web.config
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7001884.html
Copyright © 2020-2023  润新知