zoukankan      html  css  js  c++  java
  • BZOJ3295 动态逆序对(树状数组套线段树)

    [Cqoi2011]动态逆序对

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 6058  Solved: 2117
    [Submit][Status][Discuss]

    Description

    对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数。给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。

    Input

    输入第一行包含两个整数nm,即初始元素的个数和删除的元素个数。以下n行每行包含一个1到n之间的正整数,即初始排列。以下m行每行一个正整数,依次为每次删除的元素。
     

    Output

     
    输出包含m行,依次为删除每个元素之前,逆序对的个数。

    Sample Input

    5 4
    1
    5
    3
    4
    2
    5
    1
    4
    2

    Sample Output

    5
    2
    2
    1

    样例解释
    (1,5,3,4,2)(1,3,4,2)(3,4,2)(3,2)(3)。

    HINT

    N<=100000 M<=50000

    Source

    题解:

       普通的树状数组,无法记录位置,不能知道一次之后记录的是所以位置的信息,

       一次删除的时候,不能知道哪些值是比它小的,因为位置的影响,

       所以需要树套树,在开一层位置,这样就可以了,动态开点,n logn log n的空间复杂度。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cmath>
     6 
     7 #define N 100007
     8 #define M 10000007
     9 using namespace std;
    10 int n,m,cnt;
    11 int a[N],id[N],bit[N],lson[M],rson[M],tree[M];
    12 long long ans;
    13 
    14 int lowbit(int x){return x&-x;}
    15 void addy(int &u,int l,int r,int x,int y)
    16 {
    17     if(!u)u=++cnt;
    18     if(l==r){tree[u]+=y;return;}
    19     int mid=(l+r)>>1;
    20     if(x<=mid) addy(lson[u],l,mid,x,y);
    21     else addy(rson[u],mid+1,r,x,y);
    22     tree[u]=tree[lson[u]]+tree[rson[u]];
    23 }
    24 void addx(int x,int y,int val)
    25 {
    26     for (int i=x;i<=n;i+=lowbit(i))
    27         addy(i,1,n,y,val);
    28 }
    29 int queryy(int u,int l,int r,int i,int j)
    30 {
    31     if(!u) return 0;
    32     if(l==i&&r==j) return tree[u];
    33     int mid=(l+r)>>1;
    34     if(j<=mid) return queryy(lson[u],l,mid,i,j);
    35     else if(i>mid) return queryy(rson[u],mid+1,r,i,j);
    36     return queryy(lson[u],l,mid,i,mid)+queryy(rson[u],mid+1,r,mid+1,j);
    37 }
    38 int queryx(int x,int l,int r)
    39 {
    40     int ans=0;
    41     for (int i=x;i>=1;i-=lowbit(i))
    42         ans+=queryy(i,1,n,l,r);
    43     return ans;
    44 }
    45 int main()
    46 {
    47     scanf("%d%d",&n,&m),cnt=n;
    48     for(int i=1;i<=n;i++)
    49     {
    50         scanf("%d",&a[i]);
    51         ans+=(long long)queryx(i-1,a[i]+1,n);
    52         id[a[i]]=i;
    53         addx(i,a[i],1);
    54     }
    55     while(m--)
    56     {
    57         printf("%lld
    ",ans);
    58         int x;scanf("%d",&x);
    59         ans-=(long long)queryx(id[x]-1,x+1,n);
    60         ans-=(long long)queryx(n,1,x-1);
    61         ans+=(long long)queryx(id[x]-1,1,x-1);
    62         addx(id[x],x,-1);
    63     }
    64 }
  • 相关阅读:
    利用正则表达式,完成参数的替换
    使用python读取yaml文件
    python+unittet在linux与windows使用的区别
    python发送requests请求时,使用登录的token值,作为下一个接口的请求头信息
    jmeter线程组之间传参
    requests:json请求中中文乱码处理
    ddt源码修改:HtmlTestRunner报告依据接口名显示用例名字
    使用openpyxl的styles,实现写入值时加背景色
    批量数据请求接口
    locust参数化
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8124144.html
Copyright © 2011-2022 走看看