这题为啥我写得这么复杂。

首先我们不难发现,我们将序列$a$和序列$b$排序,考虑两序列内无相同元素,那么最小值显然为$\sum_{i=1}^{n} (a_i-b_i)^2$。

下面考虑做法

首先,我们将序列$a$和序列$b$离散化(以下提及序列$a$和$b$均为离散化后的数字)

然后,我们从前往后枚举序列$a$中的每一个数字,对于序列$a$中第$i$个数字$a_i$,我们在序列$b$中找出数字$a_i$的出现位置,并把它移动到序列$b$中第$i$个位置,与$a_i$对齐。

对于序列$b$,我们用一个$splay$来维护,其中会出现插入和删除操作。

时间复杂度:$O(n log n)$。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<vector>
#define M 100005
#define L long long
#define MOD 99999997
#define lc(x) ch[x][0]
#define rc(x) ch[x][1]
using namespace std; L ans=,n,a[M]={},b[M]={},c[M]={},wei[M]={};
L ch[M][]={},siz[M]={},fa[M]={},root=; void pushup(L x){siz[x]=siz[lc(x)]+siz[rc(x)]+;}
void rotate(L x,L &k){
L y=fa[x],z=fa[y];
if(y==k) k=x;
else{
if(lc(z)==y) lc(z)=x;
else rc(z)=x;
}
L l=(lc(y)!=x),r=l^;
fa[y]=x; fa[x]=z; fa[ch[x][r]]=y;
ch[y][l]=ch[x][r]; ch[x][r]=y;
pushup(y);
pushup(x);
}
void splay(L x,L &k){
while(x!=k){
L y=fa[x],z=fa[y];
if(y!=k){
if((lc(z)==y)^(lc(y)==x)) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
} void ins(L &x,L k,L id){
if(!x) return void(x=id);
if(k<=siz[lc(x)]) ins(lc(x),k,id),fa[lc(x)]=x;
else ins(rc(x),k-siz[lc(x)]-,id),fa[rc(x)]=x;
pushup(x);
}
void del(L id){
splay(id,root);
L x=lc(id),y=rc(id);
siz[id]=; fa[x]=fa[y]=;
lc(id)=rc(id)=;
if(!x) return void(root=y);
if(!y) return void(root=x);
root=x;
while(rc(x)) x=rc(x);
rc(x)=y; fa[y]=x;
splay(x,root);
} signed main(){
scanf("%d",&n);
for(L i=;i<=n;i++) scanf("%lld",a+i),c[i]=a[i];
sort(c+,c+n+);
for(L i=;i<=n;i++) a[i]=lower_bound(c+,c+n+,a[i])-c;
for(L i=;i<=n;i++) scanf("%lld",b+i),c[i]=b[i];
sort(c+,c+n+);
for(L i=;i<=n;i++) b[i]=lower_bound(c+,c+n+,b[i])-c;
for(L i=;i<=n;i++) wei[b[i]]=i; for(L i=;i<=n;i++){
siz[i]=;
ins(root,i-,i);
splay(i,root);
}
for(L i=;i<=n;i++){
int x=wei[a[i]];
splay(x,root);
L nowid=siz[lc(x)]+;
del(x);
ins(root,i-,x);
splay(x,root);
ans+=abs(i-nowid);
}
cout<<ans%MOD<<endl;
}

【NOIP2013】 火柴排队 贪心+splay的更多相关文章

  1. LOJ2609. NOIP2013 火柴排队 【树状数组】

    LOJ2609. NOIP2013 火柴排队 LINK 题目大意: 给你两个数列,定义权值∑i=1(ai−bi)^2 问最少的操作次数,最小化权值 首先需要发现几个性质 最小权值满足任意i,j不存在a ...

  2. [树状数组+逆序对][NOIP2013]火柴排队

    火柴排队 题目描述 涵涵有两盒火柴,每盒装有n根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:∑ (ai-bi)2,i=1,2,3,. ...

  3. $Noip2013/Luogu1966$ 火柴排队 贪心+离散化+逆序对

    $Luogu$ $Description$ 给定等长的$a,b$两个序列.每次可以交换一个序列中相邻两个数.求最小的交换次数使得$\sum(a_i-b_i)^2$最小. $Sol$ 交换后的序列一定满 ...

  4. NOIP2013火柴排队[逆序对]

    题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...

  5. [NOIP2013] 火柴排队(归并排序)

    题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...

  6. noip2013 火柴排队

    题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...

  7. jzoj[1438]NOIP2013火柴排队

    读题: 相邻两个火柴可以交换?两个火柴序列?嗅到了归并排序的味道. 读完题目之后,我们可以知道,如果想要交换次数最少,可以先固定一个序列不变,比如说a序列不变,变b序列 样例是 4 2 3 1 4 3 ...

  8. noip2013火柴排队_Solution

    要想对任意(ai,bi)和(aj­和b­j),当ai<aj时,都有bi<=bj:当ai>=aj时,bi>=bj,当对a进行升序排序后(b同时发生改变,从而不改变值,最后有a1& ...

  9. 洛谷P1966 火柴排队 贪心+离散化+逆序对(待补充QAQ

    正解: 贪心+离散化+逆序对 解题报告: 链接在这儿呢quq 这题其实主要难在想方法吧我觉得?学长提点了下说用贪心之后就大概明白了,感觉没有很难 但是离散化这里还是挺有趣的,因为并不是能很熟练地掌握离 ...

随机推荐

  1. css长度

    在CSS样式表中,长度单位分两种: 相对长度单位,如px, em等绝对长度单位,如pt,mm等 CSS相对长度单位(relative length unit) CSS相对长度单位中的相对二字,表明了其 ...

  2. 【Java】Eclipse在线安装SVN插件

    安装环境 系统:win7系统 软件:eclipse(Mars.2 Release (4.5.2)) 安装步骤 1. 打开eclipse软件,点击菜单栏的help——>Install New So ...

  3. const与预处理宏#define的区别

    在c语言程序设计时,预处理器可以不受限制地建立宏并用它来替代值.因为预处理器只做一些文本替换,宏没有类型检测概念,也没有类型检测功能.所以预处理器的值替换会出现一些小的问题,出现的这些问题,在c++中 ...

  4. shell的基本语法

    一 赋值运算符 1 += :使用方法是,((x+=需要增加的数字))算和值. 2 *=  :使用方法是,((x*=需要怎加的倍数))算乘值. 3 %= :使用方法是,((x%=需要除以的数字))算余数 ...

  5. 2018.10.09 NOIP模拟 世界杯(图论+set优化)

    传送门 貌似是防akakak题? 不是很清楚. 事实上如果两个人没有严格的大小关系,我们给他们两个连一条边. 这样可以构成很多连通块. 而且对于连通块a,ba,ba,b,aia_iai​和bjb_jb ...

  6. vi 基本使用命令

    说明:以下的例子中 xxx 表示在命令模式下输入 xxx 并回车以下的例子中 :xxx 表示在扩展模式下输入 xxx 并回车小括号中的命令表示相关命令在编辑模式或可视模式下输入的命令会另外注明 1 查 ...

  7. generate

    一:generate Verilog-2001添加了generate循环,允许产生module和primitive的多个实例化,同时也可以产生多个variable,net,task,function, ...

  8. Go并发编程基础(译)

    2015-05-20 三 By youngsterxyf 原文:Fundamentals of concurrent programming 译者:youngsterxyf 本文是一篇并发编程方面的入 ...

  9. jupyterlab notebook区别

    https://juejin.im/entry/5b350e52f265da59bd5ed31e Windows 7(Windows 10)安装后anaconda 命令行jupyter lab 出现4 ...

  10. (动态规划 最长有序子序列)Monkey and Banana --HDU --1069

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1069 http://acm.hust.edu.cn/vjudge/contest/view.action ...