[CF1830E] Bully Sort
题目描述
On a permutation $ p $ of length $ n $ , we define a bully swap as follows:
- Let $ i $ be the index of the largest element $ p_i $ such that $ p_i \neq i $ .
- Let $ j $ be the index of the smallest element $ p_j $ such that $ i < j $ .
- Swap $ p_i $ and $ p_j $ .
We define $ f(p) $ as the number of bully swaps we need to perform until $ p $ becomes sorted. Note that if $ p $ is the identity permutation, $ f(p)=0 $ .
You are given $ n $ and a permutation $ p $ of length $ n $ . You need to process the following $ q $ updates.
In each update, you are given two integers $ x $ and $ y $ . You will swap $ p_x $ and $ p_y $ and then find the value of $ f(p) $ .
Note that the updates are persistent. Changes made to the permutation $ p $ will apply when processing future updates.
输入格式
The first line of the input contains two integers $ n $ and $ q $ ( $ 2 \le n \le 5 \cdot 10^5 $ , $ 1 \le q \le 5 \cdot 10^4 $ ) — the length of the permutation and the number of updates.
The second line of input contains $ n $ integer $ p_1,p_2,\ldots,p_n $ ( $ 1 \leq p_i \leq n $ ) — the permutation $ p $ . All elements of $ p $ are distinct.
The $ i $ -th of the next $ q $ lines of input contains two integers $ x_i $ and $ y_i $ ( $ 1 \le x_i < y_i \le n $ ) — describing the $ i $ -th update.
神仙题。
现在主要问题是如何快速求出 \(f(p)\) 的答案。
结论是 \(\sum\limits_{i=1}^n |i-p_i|-\sum\limits_{i=1}^n\sum\limits_{j=i+1}^n[a_i>a_j]\)
因为在一次交换 \(i,j\) 时,逆序对减少 \(2(j-i)-1\) 次,\(|i-p_i|\) 减少 \(2(j-i)\) 个,于是减一下就是答案。
然后动态维护逆序对就好,我打了个常数巨大的 KDT。
#include<bits/stdc++.h>
using namespace std;
const int N=6e5+5;
typedef long long LL;
LL ans;
int n,q,mxx[N],mnx[N],mxy[N],mny[N],idx,c[N],tr[N],g[N],p[N],m;
pair<int,int>a[N];
int cmp(pair<int,int>x,pair<int,int>y)
{
return x.second^y.second? x.second<y.second:x.first<y.first;
}
int ask(int l,int r,int u,int d)
{
int o=l+r>>1;
if(l>r||mnx[o]>u||mxy[o]<d)
return 0;
if(mxx[o]<=u&&mny[o]>=d)
return c[o];
return ask(l,o-1,u,d)+ask(o+1,r,u,d)+(a[o].first<=u&&a[o].second>=d&&g[o]);
}
int build(int l,int r,int op)
{
if(l>r)
return 0;
int o=l+r>>1;
if(!op)
nth_element(a+l,a+o,a+r+1);
else
nth_element(a+l,a+o,a+r+1,cmp);
int lc=build(l,o-1,!op),rc=build(o+1,r,!op);
mxx[o]=max({mxx[lc],mxx[rc],a[o].first});
mnx[o]=min({mnx[lc],mnx[rc],a[o].first});
mxy[o]=max({mxy[lc],mxy[rc],a[o].second});
mny[o]=min({mny[lc],mny[rc],a[o].second});
return o;
}
void add(int l,int r,int a0,int a1,int t,int op)
{
int o=l+r>>1;
c[o]+=t;
if(a0==a[o].first&&a1==a[o].second)
return g[o]+=t,void();
if(!op&&make_pair(a0,a1)<a[o]||op&&cmp(make_pair(a0,a1),a[o]))
return add(l,o-1,a0,a1,t,!op),void();
add(o+1,r,a0,a1,t,!op);
}
int read()
{
int s=0;
char ch=getchar();
while(ch<'0'||ch>'9')
ch=getchar();
while(ch>='0'&&ch<='9')
s=s*10+ch-48,ch=getchar();
return s;
}
void upd(int x)
{
for(;x<=n;x+=x&-x)
tr[x]++;
}
int query(int x)
{
int ret=0;
for(;x;x-=x&-x)
ret+=tr[x];
return ret;
}
void jia(int x,int op)
{
ans+=op*abs(x-p[x]);
int k=ask(1,m,x-1,p[x]);
ans-=op*k;
ans-=op*(p[x]-x+k);
}
int main()
{
static int x[N],y[N],g[N];
mnx[0]=mny[0]=1000000000;
mxx[0]=mxy[0]=-1;
n=read(),q=read();
for(int i=1;i<=n;i++)
g[i]=p[i]=read(),a[++m]=make_pair(i,p[i]);
for(int i=1;i<=q;i++)
{
x[i]=read(),y[i]=read();
swap(g[x[i]],g[y[i]]);
a[++m]=make_pair(x[i],g[x[i]]);
a[++m]=make_pair(y[i],g[y[i]]);
}
build(1,m,0);
for(int i=1;i<=n;i++)
add(1,m,i,p[i],1,0),upd(p[i]),ans+=abs(i-p[i])-i+query(p[i]);
for(int i=1;i<=q;i++)
{
jia(x[i],-1);
jia(y[i],-1);
add(1,m,x[i],p[x[i]],-1,0);
add(1,m,y[i],p[y[i]],-1,0);
if(p[x[i]]>p[y[i]])
--ans;
swap(p[x[i]],p[y[i]]);
add(1,m,x[i],p[x[i]],1,0);
add(1,m,y[i],p[y[i]],1,0);
jia(x[i],1);
jia(y[i],1);
if(p[x[i]]>p[y[i]])
++ans;
printf("%lld\n",ans);
}
}
[CF1830E] Bully Sort的更多相关文章
- [算法]——归并排序(Merge Sort)
归并排序(Merge Sort)与快速排序思想类似:将待排序数据分成两部分,继续将两个子部分进行递归的归并排序:然后将已经有序的两个子部分进行合并,最终完成排序.其时间复杂度与快速排序均为O(nlog ...
- [算法]——快速排序(Quick Sort)
顾名思义,快速排序(quick sort)速度十分快,时间复杂度为O(nlogn).虽然从此角度讲,也有很多排序算法如归并排序.堆排序甚至希尔排序等,都能达到如此快速,但是快速排序使用更加广泛,以至于 ...
- shell之sort命令
1 sort的工作原理 sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出. [rocrocket@rocrocket progr ...
- 详细解说 STL 排序(Sort)
0 前言: STL,为什么你必须掌握 对于程序员来说,数据结构是必修的一门课.从查找到排序,从链表到二叉树,几乎所有的算法和原理都需要理解,理解不了也要死记硬背下来.幸运的是这些理论都已经比较成熟,算 ...
- SQL Tuning 基础概述06 - 表的关联方式:Nested Loops Join,Merge Sort Join & Hash Join
nested loops join(嵌套循环) 驱动表返回几条结果集,被驱动表访问多少次,有驱动顺序,无须排序,无任何限制. 驱动表限制条件有索引,被驱动表连接条件有索引. hints:use_n ...
- js sort() reverse()
数组中存在的两个方法:sort()和reverse() 直接用sort(),如下: ,,,,,,,,,,,]; console.log(array.sort());ps:[0, 1, 2, 2, 29 ...
- Java中的经典算法之冒泡排序(Bubble Sort)
Java中的经典算法之冒泡排序(Bubble Sort) 神话丿小王子的博客主页 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一 ...
- 2.sort 排序命令讲解
sort命令 sort:文本排序,仅仅是对显示文件的排序,而不影响源文件的顺序,是根据ASSII码 的字符升序来排列的. -n:安装数值大小从小到大排列 ,默认是升序. ...
- 基本shell编程【3】- 常用的工具awk\sed\sort\uniq\od
awk awk是个很好用的东西,大量使用在linux系统分析的结果展示处理上.并且可以使用管道, input | awk '' | output 1.首先要知道形式 awk 'command' fi ...
- 快速排序算法 quick sort的理解
最近做了一下算法的一些练习,感觉基础薄弱了,只是用一些已经有的东西来完成练习如quickSort(c++使用的时候是sort(起始位置,终止位置,比较函数),这个需要加头文件),但是不知道怎么推出来, ...
随机推荐
- 使用MediatR和FluentValidation实现CQRS应用程序的数据验证
本文将重点介绍如何通过MediatR的管道功能将FluentValidation集成到项目中实现验证功能. 什么是CQRS? CQRS(Command Query Responsibility Seg ...
- 原来你是这样的JAVA[05]--String
1.从概念上讲,java字符串就是Unicode字符串. 2.字符串拼接 用指定分隔符拼接字符串数组时,使用StringJoiner或者String.join()更方便: 用StringJoiner拼 ...
- 接口未配置在app.json文件中
微信小程序发布 提示 接口未配置在app.json文件中 狗血 昨天更新 就在app.json中添加 解决问题 "requiredPrivateInfos":[ "ge ...
- mysql关键字匹配度模糊查询
有时候项目中需要进行模糊查询,但是要对查询出来的结果进行匹配度排序,比如搜索关键字是"北",需要把数据库中第一个字是北的排在前面,此时就可以用mysql的INSTR函数. INST ...
- 在线PNG, JPG, BMP 转ICO图标,适用WINDOWS XP, VISTA, 7, 8, 10
在线PNG, JPG, BMP 转ICO图标网址: http://static.krpano.tech/image2ico 该网站可以把PNG, JPG和BMP图片转换成包含多个层级的ICO图标, 可 ...
- 【krpano】图文案例
KRPano图文案例可以展示图片和文字,并支持图片放大浏览,以及文本拖动等操作. 具体截图如下: 下载地址:http://pan.baidu.com/s/1qXQnPes 感谢群内小伙伴 快乐分享 本 ...
- 使用 Sealos 一键部署高可用 MinIO,开启对象存储之旅
大家好!今天这篇文章主要向大家介绍如何通过 Sealos 一键部署高可用 MinIO 集群. MinIO 对象存储是什么? 对象是二进制数据,例如图像.音频文件.电子表格甚至二进制可执行代码.对象的大 ...
- 「codeforces - 1519E」Off by One
link. 点 \(A\) 与 \((0,0)\),\(B\) 共线的充要条件是 \(\frac{y_A}{x_A}=\frac{y_B}{x_B}\),即 \(k_{OA}=k_{OB}\).又考虑 ...
- 小札 Combinatorics & Inclusion-Exclusion Principle 1
「codeforces - 340E」Iahub and Permutations link. 把 \(1,\dots,n\) 中剩下没被固定的数的数量记作 \(s\),再把这其中不担心有会填到自己身 ...
- pandas(进阶操作)-- 处理非数值型数据 -- 数据分析三剑客(核心)
博客地址:https://www.cnblogs.com/zylyehuo/ 开发环境 anaconda 集成环境:集成好了数据分析和机器学习中所需要的全部环境 安装目录不可以有中文和特殊符号 jup ...