逆序对(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进行贡献

必须满足tj,idixj" class="mathcode" src="https://private.codecogs.com/gif.latex?ti%3Etj%2Cidi%3Cidj%2Cxi%3Exj">

tj,idi>idj,xi

三维偏序就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\n",sum[i]);
}
return 0;
}

逆序对(inversion)的更多相关文章

  1. 逆序对 inversion

      评测传送门 [问题描述] 有一个1 − n的排列,你会依次进行m次操作,第i次操作表示为(x i , y i ),交换以这两个 值为下标的元素,每次操作有一半的概率成功,你需要求出最后序列的逆序对 ...

  2. HDU 1394Minimum Inversion Number 数状数组 逆序对数量和

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  3. HDU-1394 Minimum Inversion Number 线段树+逆序对

    仍旧在练习线段树中..这道题一开始没有完全理解搞了一上午,感到了自己的shabi.. Minimum Inversion Number Time Limit: 2000/1000 MS (Java/O ...

  4. UVA 11990 ``Dynamic'' Inversion 动态逆序对

    ``Dynamic'' Inversion Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://uva.onlinejudge.org/index ...

  5. hdu 5497 Inversion 树状数组 逆序对,单点修改

    Inversion Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5497 ...

  6. 浙江工商大学15年校赛I题 Inversion 【归并排序求逆序对】

    Inversion Time Limit 1s Memory Limit 131072KB Judge Program Standard Ratio(Solve/Submit) 15.00%(3/20 ...

  7. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  8. SPOJ:Another Version of Inversion(二维数组的逆序对)

    DCE Coders admins are way much geekier than they actually seem! Kartik has been following that tradi ...

  9. 线段树 逆序对 Minimum Inversion Number HDU - 1394 Laptop

    Minimum Inversion Number HDU - 1394 求最小反转数,就是求最少的逆序对. 逆序对怎么求,就是先把所有的数都初始化为0,然后按照顺序放入数字,放入数字前查询从这个数往后 ...

随机推荐

  1. python_51_函数返回值1

    def test1(): '只执行return以前的' print('test1返回值为0 ') return 0 print('这句不会被执行的') x=test1() print(x)#值为0 d ...

  2. mongdb 一些操作

    一.命令操作数据库1.管理员身份打开cmd2.进到mongdb的mongo.exe文件所在路径3.show dbs 查看mongodb4.连接远程数据库:mongo ip:端口/数据库5.打开某个数据 ...

  3. form 表单 和 jQuery HTML / CSS 方法($().html 类似的样式)

    1 有关链接 :http://www.runoob.com/tags/tag-form.html https://www.cnblogs.com/Jxwz/p/4509618.html https:/ ...

  4. Spring学习记录(一)

    1.Spring简介 Spring是一个轻量级的java开发框架.框架的主要优势之一就是分层架构,Spring使用基本的JavaBean,不仅限于服务器的开发.从简单性,可测试性和松耦合的角度而言,任 ...

  5. IE脚本调试

    打开IE -- 工具 -- Internet选项 -- 高级 --有4项. 1.禁用脚本调试(Internet Explorer)(去掉对勾) 2.禁用脚本调试(其他)(去掉对勾) 3.显示每个脚本错 ...

  6. C#赋值运算符

    一.C#赋值运算符 C#语言的赋值运算符用于将一个数据赋予一个变量.属性或者引用.数据可以是常量.变量或者表达式. 1. 简单赋值 “=”操作符被称为简单赋值操作符.在一个简单赋值中,右操作数必须为某 ...

  7. JDBC 基本语法总结

    实现JDBC操作: 静态SQL执行 ① 注册驱动 Class.forName("com.mysql.jdbc.Driver"); ② 创建连接 Connection con = D ...

  8. JQuery根据关键字检索html元素并筛选显示

    背景:标题比较唬人,实际上就是在文本框中输入关键字,通过关键字检索html元素,筛选后显示在界面上. Html元素如下: <div> <input type="text&q ...

  9. JS - Array.slice 与 Array.splice

    1)Array.slice方法   1.1)接收两个参数:              a:起始下标              b:结束下标   1.2)返回由a(包括)至b(不包括)的元素所组成的数组 ...

  10. Python9-前端基础知识-day47

    web开发本质: 1.浏览器输入网址回车都发生了什么? 1.浏览器给服务端发送一个消息 2.服务端拿到消息 3.服务端返回消息 4.浏览器展示页面C/S架构----B/S架构客户端和服务端 消息的格式 ...