首页 > 其他分享 >2819. 动态逆序对

2819. 动态逆序对

时间:2022-10-12 13:13:03浏览次数:80  
标签:删除 int 元素 2819 mid 逆序 动态 define

题目链接

2819. 动态逆序对

对于序列 \(A\),它的逆序对数定义为满足 \(i < j\),且 \(A_i > A_j\) 的数对 \((i,j)\) 的个数。

给 \(1\) 到 \(n\) 的一个排列,按照某种顺序依次删除 \(m\) 个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。

输入格式

第一行包含两个整数 \(n\) 和 \(m\),即初始元素的个数和删除的元素个数。

以下 \(n\) 行每行包含一个 \(1\) 到 \(n\) 之间的正整数,即初始排列。

以下 \(m\) 行每行一个正整数,依次为每次删除的元素。

输出格式

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

数据范围

\(1 \le n \le 10^5\),
\(1 \le m \le 50000\)

输入样例:

5 4
1
5
3
4
2
5
1
4
2

输出样例:

5
2
2
1

样例解释

给定序列变化依次为 \((1,5,3,4,2) \to (1,3,4,2) \to (3,4,2) \to (3,2) \to (3)\)。

解题思路

cdq分治

按时间增加一个维度:时间戳,每次删除都有一个唯一的时间戳 \(t\),其他没有删除的数的时间戳可任意指定,为方便后面树状数组的处理,每次删除将时间戳倒序处理,对于元素 \(i\),求出删除 \(i\) 之前,即 \(t_i\) 之前,满足 \(i<j,a[i]>a[j]\) 或 \(i>j,a[i]<a[j]\) 的对数,即对于 \(t_i<t_j\),求出 \(i<j,a[i]>a[j]\) 或 \(i>j,a[i]<a[j]\) 的对数即可,故需要两遍 \(cdq分治\),另外,里面双指针的位置等信息需要考虑一下

  • 时间复杂度:\(O(nlgn^2n)\)

代码

// Problem: 动态逆序对
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/2821/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=1e5+5;
int n,m,pos[N],tr[N];
LL res[N];
struct A
{
	int p,t,res;
}a[N],b[N];
void add(int x,int y)
{
	for(;x<N;x+=x&-x)tr[x]+=y;
}
int ask(int x)
{
	int res=0;
	for(;x;x-=x&-x)res+=tr[x];
	return res;
}
void merge_sort(int l,int r)
{
	if(l>=r)return ;
	int mid=l+r>>1;
	merge_sort(l,mid),merge_sort(mid+1,r);
	int j=l,i=mid+1;
	while(j<=mid&&i<=r)
		if(a[i].p<a[j].p)add(a[i].t,1),i++;
		else
			a[j].res+=ask(a[j].t-1),j++;
	while(j<=mid)a[j].res+=ask(a[j].t-1),j++;
	for(int k=mid+1;k<i;k++)add(a[k].t,-1);
	
	i=mid,j=r;
	while(i>=l&&j>=mid+1)
		if(a[i].p>a[j].p)add(a[i].t,1),i--;
		else
			a[j].res+=ask(a[j].t-1),j--;
	while(j>=mid+1)a[j].res+=ask(a[j].t-1),j--;
	for(int k=i+1;k<=mid;k++)add(a[k].t,-1);
	
	int k=0;
	i=l,j=mid+1;
	while(i<=mid&&j<=r)
		if(a[i].p<a[j].p)b[++k]=a[i++];
		else
			b[++k]=a[j++];
	while(i<=mid)b[++k]=a[i++];
	while(j<=r)b[++k]=a[j++];
	for(int i=l,j=1;j<=k;j++,i++)a[i]=b[j];
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i].p,pos[a[i].p]=i;
    for(int i=n,j=1;j<=m;j++,i--)
    {
    	int p;
    	cin>>p;
    	a[pos[p]].t=i;
    	pos[p]=-1;
    }
    for(int i=1,j=n+1-m;i<=n;i++)
    	if(pos[a[i].p]!=-1)a[i].t=--j;
    merge_sort(1,n);
    for(int i=1;i<=n;i++)res[a[i].t]=a[i].res;
    for(int i=1;i<=n;i++)res[i]+=res[i-1];
    for(int i=n;i>=n+1-m;i--)cout<<res[i]<<'\n';
    return 0;
}

标签:删除,int,元素,2819,mid,逆序,动态,define
From: https://www.cnblogs.com/zyyun/p/16784171.html

相关文章

  • 算法导论(第15章 动态规划)*
    目录15.1钢条切割自顶向下递归实现使用动态规划方法求解最优钢条切割问题动态规划(dynamicprogramming)与分治方法相似,都是通过组合子问题的解来求解原问题(在这里,“prog......
  • element-ui的form表单验证如何给动态的prop
    <template><el-form:model='queryForm'ref='queryForm'><divv-for="(item,index)inqueryForm.tags"><el-form-item:prop="`tags[${inde......
  • 动态拨号安装Ubuntu系统使用说明
    现有的Ubuntu系统为ubuntu18.04.2版本。安装Ubuntu系统后,使用linux远程信息进行远程连接可用putty、Xshell等工具进行远程连接与Centos系统不同的是,拨号命令的变化,拨号不再......
  • 动态拨号安装系统使用说明
    现有的centos系统包含了6.10版本和7.6版本。安装centos系统后,使用linux远程信息进行远程连接可用putty、Xshell等工具进行远程连接默认是未拨号的状态,是没有网络的,通过pppoe......
  • 数据结构 玩转数据结构 2-7 动态数组
    0课程地址https://coding.imooc.com/lesson/207.html#mid=13412 1重点关注1.1数组动态伸缩参见3.1coding 1.2泛型数组参见3.2......
  • VS2019 使用 C/C++ 动态链接库 并 进行调用
     vs2019生成dll并调用的实现示例:​​https://www.jb51.net/article/179759.htm​​ 1.VS 中生成动态链接库的三种方式(导出函数) 开发环境:VS2019 创建动态链接库项目新......
  • MySQL动态执行字符串
    需求表中存有按天维度字符串表达式字段,需要取出,然后计算出字符串表达式的结果,最后得到一个结果集,并且保留结果例:表达式字段值为value>1,需要先replace掉value为实际......
  • Mybatis实现@Select@Update等注解动态查询或更新SQL语句
    通过自己实现LanguageDriver,在服务器启动的时候,就会将我们自定义的标签解析为动态SQL语句。例如,写个构造updatein的动态sql更新,代码如下:packagecom.ljw.web.common.my......
  • 【程序员必会十大算法】之动态规划算法(背包问题)
    1.动态规划算法动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动......
  • vue-动态菜单 带本地动态路由结合
    思路:方法1.按照以往的动态菜单来做,就是根据权限调取后端接口,获取相应的菜单数据,对数据进行处理,添加到路由对象中方法2.自己在router.js中写全部的路由,然后设置一个标识,可......