题目描述

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的更多相关文章

  1. [算法]——归并排序(Merge Sort)

    归并排序(Merge Sort)与快速排序思想类似:将待排序数据分成两部分,继续将两个子部分进行递归的归并排序:然后将已经有序的两个子部分进行合并,最终完成排序.其时间复杂度与快速排序均为O(nlog ...

  2. [算法]——快速排序(Quick Sort)

    顾名思义,快速排序(quick sort)速度十分快,时间复杂度为O(nlogn).虽然从此角度讲,也有很多排序算法如归并排序.堆排序甚至希尔排序等,都能达到如此快速,但是快速排序使用更加广泛,以至于 ...

  3. shell之sort命令

    1 sort的工作原理 sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出. [rocrocket@rocrocket progr ...

  4. 详细解说 STL 排序(Sort)

    0 前言: STL,为什么你必须掌握 对于程序员来说,数据结构是必修的一门课.从查找到排序,从链表到二叉树,几乎所有的算法和原理都需要理解,理解不了也要死记硬背下来.幸运的是这些理论都已经比较成熟,算 ...

  5. SQL Tuning 基础概述06 - 表的关联方式:Nested Loops Join,Merge Sort Join & Hash Join

    nested loops join(嵌套循环)   驱动表返回几条结果集,被驱动表访问多少次,有驱动顺序,无须排序,无任何限制. 驱动表限制条件有索引,被驱动表连接条件有索引. hints:use_n ...

  6. js sort() reverse()

    数组中存在的两个方法:sort()和reverse() 直接用sort(),如下: ,,,,,,,,,,,]; console.log(array.sort());ps:[0, 1, 2, 2, 29 ...

  7. Java中的经典算法之冒泡排序(Bubble Sort)

    Java中的经典算法之冒泡排序(Bubble Sort) 神话丿小王子的博客主页 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一 ...

  8. 2.sort 排序命令讲解

    sort命令  sort:文本排序,仅仅是对显示文件的排序,而不影响源文件的顺序,是根据ASSII码     的字符升序来排列的.        -n:安装数值大小从小到大排列 ,默认是升序.     ...

  9. 基本shell编程【3】- 常用的工具awk\sed\sort\uniq\od

    awk awk是个很好用的东西,大量使用在linux系统分析的结果展示处理上.并且可以使用管道, input | awk ''  | output 1.首先要知道形式 awk 'command' fi ...

  10. 快速排序算法 quick sort的理解

    最近做了一下算法的一些练习,感觉基础薄弱了,只是用一些已经有的东西来完成练习如quickSort(c++使用的时候是sort(起始位置,终止位置,比较函数),这个需要加头文件),但是不知道怎么推出来, ...

随机推荐

  1. 国标GB28181视频平台EasyGBS视频监控平台无法播放,抓包返回ICMP排查过程

    国标GB28181视频平台EasyGBS是基于国标GB/T28181协议的行业内安防视频流媒体能力平台,可实现的视频功能包括:实时监控直播.录像.检索与回看.语音对讲.云存储.告警.平台级联等功能.国 ...

  2. 几种常用到的 Hybrid App 技术框架

    移动操作系统在经历了诸神混战之后,BlackBerry OS.Symbian OS.Windows Phone 等早期的移动操作系统逐渐因失去竞争力而退出.目前,市场上主要只剩下安卓和 iOS 两大阵 ...

  3. 10、Spring之AOP概述

    10.1.概念 AOP(Aspect Oriented Programming)是一种设计思想,是软件设计领域中的面向切面编程 AOP是面向对象编程(OOP)的一种补充和完善,OOP是纵向继承机制,A ...

  4. 简单对比一下 C 与 Go 两种语言

    以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/U6jIT837x5Yxe6Ev1aMDsA 使用一个简单的计数程序将 ...

  5. 京东工业根据ID取商品详情 API

    item_get-根据ID取商品详情  注册开通 vipmro.item_get 公共参数 名称 类型 必须 描述 key String 是 调用key(必须以GET方式拼接在URL中) secret ...

  6. 淘宝详情api接口的应用

    淘宝详情API接口是一个基于HTTP协议的接口服务,可用于获取淘宝商品的具体信息.下面将介绍如何调用淘宝详情API接口获取淘宝商品数据的步骤. 1.注册账号并创建应用 首先,我们需要进行账号注册.实名 ...

  7. 文心一言 VS 讯飞星火 VS chatgpt (85)-- 算法导论8.2 2题

    二.用go语言,试证明 COUNTING-SORT 是稳定的. 文心一言: 要证明 COUNTING-SORT 是稳定的,我们需要证明在排序过程中,具有相同值的元素在排序后仍保持其原始的相对顺序.CO ...

  8. mysql 大表如何ddl 👑

    大家好,我是蓝胖子,mysql对大表(千万级数据)的ddl语句,在生产上执行时一定要千万小心,一不小心就有可能造成业务阻塞,数据库io和cpu飙高的情况.今天我们就来看看如何针对大表执行ddl语句. ...

  9. jenkins部署及gitlab联调

    jenkins部署及gitlab联调 目录 jenkins部署及gitlab联调 一.jenkins安装 1.环境优化 2.安装jdk java 环境 3.下载jenkins 4.启动Jenkins服 ...

  10. FFmpeg: How To Convert MP4 Video To MP3 Audio?

       FFmpeg: How To Convert MP4 Video To MP3 Audio? Learn how to Convert an MP4 Video to MP3 Audio wit ...