zoukankan      html  css  js  c++  java
  • bzoj3295 [Cqoi2011]动态逆序对 cdq+树状数组

    【bzoj3295】[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

    题解:

        这道动态逆序对问题和普通逆序对问题有什么区别,发现动态逆序对的每个值还有一个时间影响

        普通逆序对只有两个元素是二维偏序问题,一维是位置,一维是键值。

        而这里就是三维偏序问题,我们应该怎么来安排可以最方便呢?

        我是这样安排的,a,b,c分别表示时间,位置,键值,分别排序+cdq+树状数组,这样来搞

        在对于键值中,有点技巧,应为位置可能在前或者在后面,所以两次树状数组维护才行。

        最后用前缀和的思想。

     1 #include<cstring>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstdio>
     6 
     7 #define N 100007
     8 using namespace std;
     9 inline int read()
    10 {
    11     int x=0,f=1;char ch=getchar();
    12     while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 
    17 int n,m,tr[N];
    18 long long ans[N];
    19 struct Node
    20 {
    21     int a,b,c,ans;
    22 }a[N];
    23 
    24 bool cmp1(Node x,Node y)
    25 {
    26     if (x.a==y.a&&x.b==y.b) return x.c>y.c;
    27     if (x.a==y.a) return x.b<y.b;
    28     return x.a<y.a;
    29 }
    30 bool cmp2(Node x,Node y)
    31 {
    32     return x.b<y.b;
    33 }
    34 bool cmp3(Node x,Node y)
    35 {
    36     return x.b>y.b;
    37 }
    38 int lowbit(int x){return x&(-x);}
    39 void update(int x,int num)
    40 {
    41     for (int i=x;i<=n;i+=lowbit(i))
    42         tr[i]+=num;
    43 }
    44 int query(int x)
    45 {
    46     int res=0;
    47     for (int i=x;i>=1;i-=lowbit(i))
    48         res+=tr[i];
    49     return res;    
    50 }
    51 void cdq(int l,int r)
    52 {
    53     if (l==r) return;
    54     int mid=(l+r)>>1;
    55     cdq(l,mid);
    56     cdq(mid+1,r);
    57     sort(a+l,a+mid+1,cmp2);
    58     sort(a+mid+1,a+r+1,cmp2);
    59     int i=l,j=mid+1;
    60     while(j<=r)
    61     {
    62         while(i<=mid&&a[i].b<a[j].b)
    63             update(a[i].c,1),i++;
    64         a[j].ans+=query(n)-query(a[j].c),j++;
    65     }
    66     for (int j=l;j<i;j++)
    67         update(a[j].c,-1);
    68         
    69     sort(a+l,a+mid+1,cmp3);
    70     sort(a+mid+1,a+r+1,cmp3);
    71     i=l,j=mid+1;
    72     while(j<=r)
    73     {
    74         while(i<=mid&&a[i].b>a[j].b)
    75             update(a[i].c,1),i++;
    76         a[j].ans+=query(a[j].c),j++;
    77     }
    78     for (int j=l;j<i;j++)
    79         update(a[j].c,-1);
    80 }
    81 int main()
    82 {
    83     n=read(),m=read();
    84     for (int i=1;i<=n;i++){int x=read();a[x].b=i;}
    85     for (int i=1;i<=m;i++){int x=read();a[x].a=m-i+1;}//倒着表示什么时候插入 
    86     for (int i=1;i<=n;i++)a[i].c=i;
    87     sort(a+1,a+n+1,cmp1);
    88     cdq(1,n);
    89     for (int i=1;i<=n;i++)
    90         ans[a[i].a]+=a[i].ans;
    91     for (int i=1;i<=m;i++)
    92         ans[i]+=ans[i-1];
    93     for (int i=m;i>=1;i--)
    94         printf("%lld
    ",ans[i]);
    95 }
  • 相关阅读:
    Windows 编程入门,了解什么是UWP应用。
    java getway springcloud 记录请求数据
    nginx服务器配置传递给下一层的信息的一些参数-设置哪些跨域的域名可访问
    e.printStackTrace() 原理的分析
    关于性能测试组出现的问题查询和优化
    springboot connecting to :mongodb://127.0..0.1:27017/test authentication failed
    redis 集群 slots are covered by nodes.
    @PostConstruct +getapplicationcontext.getbean springboot获取getBean
    idea 错误: 找不到或无法加载主类 xx.xxx.Application
    elastic-job和spring cloud版本冲突2
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7985098.html
Copyright © 2011-2022 走看看