zoukankan      html  css  js  c++  java
  • 逆序对(inversion)

    逆序对(inversion)

    题目描述

    对于序列AA,它的逆序对数定义为满足i<ji<j,且Ai>AjAi>Aj 的数对i,ji,j的个数。

    现给你11到nn的一个排列,并按照某种顺序依次删除mm个元素。现请你求出在每次删除一个元素之前整个序列的逆序对总个数。

    输入

    第一行包含两个整数nn和mm。

    第二行包含nn个数,代表初始序列。

    接下来的mm行,每一个整数表示第ii行,每一个整数表示第ii次删除的数(保证在此之前未曾删除过)。

    输出

    共mm行,表示第ii次删数前整个序列的逆对总个数。

    样例输入

    5 4
    1 5 3 4 2
    5
    1
    4
    2

    样例输出

    5
    2
    2
    1

    提示


    动态逆序对

    假设删除时间为ti,值为xi,下标idi

    如果i要对j进行贡献

    必须满足ti>tj,idi<idj,xi>xj

    ti>tj,idi>idj,xi<xj

    三维偏序就CDQ啦

    看错题调一天

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define maxn 1000005
    #define ll long long
    using namespace std;
    int n,m,c;
    ll sum[maxn],tree[maxn],ans[maxn];
    int p[maxn];
    struct node{
        int id,x,t;
    }s[maxn],a[maxn];
    bool cmp(node a,node b){
        return a.t>b.t;
    }
    bool X(node a,node b){
        return a.x>b.x;
    }
    bool ID(node a,node b){
        return a.id>b.id;
    }
    void jia(int k,int val){
        for(int i=k;i<=n;i+=i&-i)tree[i]+=val;
    }
    ll ask(int k){
        ll su=0;
        for(int i=k;i;i-=i&-i)su+=tree[i];
        return su;
    }
    void cdq(int l,int r){
        if(l==r)return;
        int mid=(l+r)>>1;
        cdq(l,mid);cdq(mid+1,r);
        sort(s+l,s+mid+1,X);sort(s+mid+1,s+r+1,X);
        //cout<<l<<' '<<r<<endl;
        int i=l;
        for(int j=mid+1;j<=r;j++){
            while(s[i].x>s[j].x&&i<=mid){
                jia(s[i].id,1);i++;
                //cout<<s[i].id<<' ';
            }
            ans[s[j].t]+=ask(s[j].id);
        }
        for(int j=l;j<i;j++)jia(s[j].id,-1);
        //merge(s+l,s+mid+1,s+mid+1,s+r+1,a,X);
        //for(int i=0;i<=l+r-1;i++)s[i+l]=a[i];
    }
     
    void cd(int l,int r){
        if(l==r)return;
        int mid=(l+r)>>1;
        cd(l,mid);cd(mid+1,r);
        sort(s+l,s+mid+1,ID);sort(s+mid+1,s+r+1,ID);
        int i=l;
        for(int j=mid+1;j<=r;j++){
            while(s[i].id>s[j].id&&i<=mid){
                jia(s[i].x,1);i++;
            }
            ans[s[j].t]+=ask(s[j].x);
        }
        for(int j=l;j<i;j++)jia(s[j].x,-1);
        //merge(s+l,s+mid+1,s+mid+1,s+r+1,a,ID);
        //for(int i=0;i<=l+r-1;i++)s[i+l]=a[i];
    }
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            scanf("%d",&s[i].x);p[s[i].x]=i;
            s[i].id=i;
        }
        for(int i=1;i<=m;i++){
            scanf("%d",&c);
            s[p[c]].t=i;
        }
        int top=m;
        for(int i=1;i<=n;i++)if(!s[i].t)s[i].t=++top;
        sort(s+1,s+n+1,cmp);
        cdq(1,n);
        sort(s+1,s+n+1,cmp);
        cd(1,n);
        for(int i=n;i>=1;i--)sum[i]=sum[i+1]+ans[i];
    //    for(int i=1;i<=n;i++) cout<<ans[i]<<" ";cout<<endl;
        for(int i=1;i<=m;i++){
            printf("%lld
    ",sum[i]);
        }
        return 0;
    }
  • 相关阅读:
    【SSM 8】spring集成Mybatis通用Mapper
    【SSM 7】Mybatis底层封装思路
    【SSM 7】Mybatis底层封装思路
    【SSM 6】Spring+SpringMVC+Mybatis框架搭建步骤
    【SSM 6】Spring+SpringMVC+Mybatis框架搭建步骤
    【SSM 5】Mybatis分页插件的使用
    【SSM 5】Mybatis分页插件的使用
    (2018干货系列十)最新android开发学习路线整合
    (2018干货系列九)最新软件测试学习路线整合
    (2018干货系列八)最新VR学习路线整合
  • 原文地址:https://www.cnblogs.com/liankewei/p/10358846.html
Copyright © 2011-2022 走看看