zoukankan      html  css  js  c++  java
  • uva11990 动态逆序对

    这题说的是给了一个数组,按照他给的顺序依次删除数,在删除之前输出此时的逆序对个数

    我们用Fenwick树 维护这整个数列, C[i]是一个 treap的头, 管理了在树状数组中 能影响他的点,然后我们用名次树去计算 在C[i]下小于等于要删除的那个数的个数就ok了。

    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include <vector>
    #include <cstdio>
    #include <stdlib.h>
    using namespace std;
    const int maxn=200005;
    struct Node
    {
        Node *ch[2];
        int r;
        int s;
        int v;
        int vloc;
        int cmp(int x)const
        {
            if(x==v)return -1;
            return x<v?0:1;
        }
        void maintain()
        {
            s=ch[0]->s+ch[1]->s+vloc;
        }
    };
    Node *null=new Node();
    void rotate(Node *&o, int d)
    {
        Node *k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
        o->maintain();k->maintain(); o=k;
    }
    void insert(Node *&o,int x)
    {
        if(o==null){
            o=new Node();
            o->ch[0]=o->ch[1]=null; o->v=x; o->r=rand();o->vloc=1;o->s=1;
        }else{
           int d=o->cmp(x);
           if(d==-1){
             o->vloc+=1;
           }else{
             insert(o->ch[d],x);if( o->ch[d]->r > o->r) rotate(o,d^1);
           }
        }
        o->maintain();
    }
    void remove(Node *&o, int x)
    {
        int d=o->cmp(x);
        if(d==-1){
            if(o->vloc > 1){
                 o->vloc-=1;
            }else if(o->ch[0]==null)o=o->ch[1];
            else if(o->ch[1]==null) o=o->ch[0];
            else{
                int d2 = o->ch[0]->r > o->ch[1]->r ? 1 : 0 ;
                rotate(o,d2); remove(o->ch[d2],x);
            }
        }else remove(o->ch[d],x);
        if(o!=null)
        o->maintain();
    }
    int find(Node *o,int x)
    {
        int num=0;
        while(o!=null)
        {
            int d=o->cmp(x);
            if(d==-1){
                num += o->ch[0]->s + o->vloc ;
                break;
            }else if(d==1){
                num+=o->ch[0]->s+o->vloc;
                o=o->ch[1];
            }else{
                o=o->ch[0];
            }
        }
        return num;
    }
    Node *C[maxn];
    int cc[maxn],A[maxn];
    int lowbit(int x)
    {
        return (-x)&x;
    }
    void init(int n)
    {
        for(int i=0; i<=n; i++)
            C[i]=null,cc[i]=0;
    }
    int N,M;
    void add1(int x, int v)
    {
        while(x<=N){
            cc[x]+=v;
            x+=lowbit(x);
        }
    }
    int sum1(int x){
        int ans=0;
        while(x>0){
            ans+=cc[x];
            x-=lowbit(x);
        }
        return ans;
    }
    void delet(int x,int v)
    {
          while(x<=N)
          {
              remove(C[x],v);
              x+=lowbit(x);
          }
    }
    int summ(int x,int v)
    {
        int ans=0;
         while(x>0)
        {
           ans+=find(C[x],v);
           x-=lowbit(x);
        }
        return ans;
    }
    int main()
    {
        null->s=0;
    
        while(scanf("%d%d",&N,&M)==2)
        {
           init(N);
           long long ans=0;
           for(int i=1; i<=N; i++)
            {
                int d;
                scanf("%d",&d);
                A[d]=i;
                ans+=sum1(N)-sum1(d);
                add1(d,1);
                int loc=i;
                while(loc<=N)
                {
                    insert(C[loc],d); loc+=lowbit(loc);
                }
           }
           for(int i=1; i<=M; i++)
            {
                int d;
                printf("%lld
    ",ans);
                scanf("%d",&d);
                int s1xiaoyu=summ(A[d],d);
                int ss1=sum1(A[d]);
                ans-=(ss1-s1xiaoyu);
                int s2xiaoyu=summ(N,d);
                ans-=s2xiaoyu-s1xiaoyu;
                add1(A[d],-1);
                delet(A[d],d);
            }
        }
        return 0;
    }
    /*
    5 4
    1
    5
    3
    4
    2
    5
    1
    4
    2
    */
    View Code
  • 相关阅读:
    Python assert(断言)
    Python importlib(动态导入模块)
    Python 异常处理
    Qt Clipboard剪贴板简单使用
    Qt5 QTableWidget设置列表自动适应列宽
    Fix VNC Desktop Sharing on Ubuntu Desktop 14.04
    Golang 交叉编译
    stdobj to array php
    Elasticsearch-集群原理
    Elasticsearch-基本操作2
  • 原文地址:https://www.cnblogs.com/Opaser/p/4906530.html
Copyright © 2011-2022 走看看