zoukankan      html  css  js  c++  java
  • [CQOI2011]动态逆序对

    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

    树状数组+主席树

    每一次删除x,我们求出前面大于x和后面小于x的个数减去

    这个用按位置作为前缀加入元素的主席树

    但有一个问题就是,作为前缀的一个元素x被删,后面的x+1~n就都要修改更新

    这样就会退化成O(n^2logn)

    所以用树状数组维护主席树

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define lowbit(x) ((x)&(-(x)))
     7 using namespace std;
     8 typedef long long lol;
     9 int pos,root[100001],ch[90*100001][2],n,m,a[100001],p[100001];
    10 lol ans;
    11 int sum[90*100001];
    12 void update(int &rt,int l,int r,int x,int d)
    13 {
    14   if (!rt)
    15       rt=++pos;
    16   sum[rt]+=d;
    17   if (l==r) return;
    18   int mid=(l+r)>>1;
    19   if (x<=mid) update(ch[rt][0],l,mid,x,d);
    20   else update(ch[rt][1],mid+1,r,x,d);
    21 }
    22 lol query1(int rt,int l,int r,int x)
    23 {
    24   if (l==r) return sum[rt];
    25   int mid=(l+r)>>1;
    26   if (x<=mid) return query1(ch[rt][0],l,mid,x)+sum[ch[rt][1]];
    27   else return query1(ch[rt][1],mid+1,r,x);
    28 }
    29 lol query2(int rt,int l,int r,int x)
    30 {
    31   if (l==r)
    32     return sum[rt];
    33   int mid=(l+r)>>1;
    34   if (x<=mid) return query2(ch[rt][0],l,mid,x);
    35   else return query2(ch[rt][1],mid+1,r,x)+sum[ch[rt][0]];
    36 }
    37 int main()
    38 {int i,j,x,k;
    39   cin>>n>>m;
    40   for (i=1;i<=n;++i)
    41     {
    42       scanf("%d",&a[i]);
    43       p[a[i]]=i;
    44       for (j=i;j<=n;j+=lowbit(j))
    45     update(root[j],1,n,a[i],1);
    46     }
    47   for (i=1;i<=n;++i)
    48     {
    49       for (j=i-1;j;j-=lowbit(j))
    50     ans+=query1(root[j],1,n,a[i]);
    51     }
    52   for (i=1;i<=m;++i)
    53     {
    54       scanf("%d",&x);
    55       printf("%lld
    ",ans);
    56       k=p[x];
    57       for (j=k-1;j;j-=lowbit(j))
    58     ans-=query1(root[j],1,n,x);
    59       for (j=k;j;j-=lowbit(j))
    60     ans+=query2(root[j],1,n,x);
    61       for (j=n;j;j-=lowbit(j))
    62     ans-=query2(root[j],1,n,x);
    63       for (j=k;j<=n;j+=lowbit(j))
    64     update(root[j],1,n,x,-1);
    65     }
    66 }
  • 相关阅读:
    扯一下关于魔兽改键的蛋
    Emacs23.3在ubuntu10.10下的手动编译与安装
    GRUB2英文文档的部分翻译
    WinForm中Crossthread operation not valid错误的解决方法
    C# 嵌入式资源
    raster配准
    excel vba 玫瑰图 风速 风向
    使用UserControl好处
    How does ArcSDE use Oracle Spatial? arcsde怎么使用oracle spatial
    信息抽取的定义(definition of information extraction)
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8250060.html
Copyright © 2011-2022 走看看