NOIp2013 火柴排队【逆序对/思维】 By cellur925
题目大意:给你两列数\(ai\)和\(bi\),你可以交换每列数中相邻的两个数,求一个最小交换次数使\(\sum_{i=1}^{n}(a_i-b_i)^2\) 最小。
最后满足条件的两个序列一定是各个数在各自序列中排名相等的情况(证明不会)。那么我们可以先把两个数组进行离散化,然后将其中一个数组以另一个数组为基准进行排序,构造出一个新数列,它应该是最后合法的序列。从原序列变到这里的步数怎么求?就是逆序对了。因为要变成升序(相对原来的数的位置)。这里用的是线段树。
#include<cstdio>
#include<algorithm>
#define maxn 100090
using namespace std;
typedef long long ll;
const ll moder=99999997;
int n;
ll ans;
int A[maxn],B[maxn],tmp[maxn];
struct SegmentTree{
int l,r;
ll sum;
}t[maxn<<4];
void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r;
if(l==r) return ;
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
}
int ask(int p,int l,int r)
{
if(t[p].l==l&&t[p].r==r) return t[p].sum;
int mid=(t[p].l+t[p].r)>>1;
if(l>mid) return ask(p<<1|1,l,r);
else if(r<=mid) return ask(p<<1,l,r);
else return ask(p<<1,l,mid)+ask(p<<1|1,mid+1,r);
}
void change(int p,int x)
{
if(t[p].l==x&&t[p].r==x)
{
t[p].sum++;
return ;
}
int mid=(t[p].l+t[p].r)>>1;
if(x<=mid) change(p<<1,x);
else change(p<<1|1,x);
(t[p].sum=t[p<<1].sum+t[p<<1|1].sum)%=moder;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&A[i]),tmp[i]=A[i];
sort(tmp+1,tmp+1+n);
// int m=unique(tmp+1,tmp+1+n)-(tmp+1);
for(int i=1;i<=n;i++) A[i]=lower_bound(tmp+1,tmp+1+n,A[i])-tmp;
for(int i=1;i<=n;i++) scanf("%d",&B[i]),tmp[i]=B[i];
sort(tmp+1,tmp+1+n);
// m=unique(tmp+1,tmp+1+n)-(tmp+1);
for(int i=1;i<=n;i++) B[i]=lower_bound(tmp+1,tmp+1+n,B[i])-tmp;
for(int i=1;i<=n;i++) tmp[B[i]]=i;
for(int i=1;i<=n;i++) A[i]=tmp[A[i]];
// for(int i=1;i<=n;i++) printf("%d ",A[i]);
// return 0;
build(1,1,n);
for(int i=1;i<=n;i++)
{
if(A[i]!=n)
(ans+=ask(1,A[i]+1,n))%=moder;
change(1,A[i]);
}
printf("%lld\n",ans);
return 0;
}
NOIp2013 火柴排队【逆序对/思维】 By cellur925的更多相关文章
- NOIP2013火柴排队[逆序对]
题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...
- luogu P1966 火柴排队 (逆序对)
luogu P1966 火柴排队 题目链接:https://www.luogu.org/problemnew/show/P1966 显然贪心的想,排名一样的数相减是最优的. 证明也很简单. 此处就不证 ...
- P1966 火柴排队——逆序对(归并,树状数组)
P1966 火柴排队 很好的逆序对板子题: 求的是(x1-x2)*(x1-x2)的最小值: x1*x1+x2*x2-2*x1*x2 让x1*x2最大即可: 可以证明将b,c数组排序后,一一对应的状态是 ...
- P1966 火柴排队(逆序对)
P1966 火柴排队 题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi) ...
- 洛谷P1966 火柴排队(逆序对)
题意 题目链接 Sol 不算很难的一道题 首先要保证权值最小,不难想到一种贪心策略,即把两个序列中rank相同的数放到同一个位置 证明也比较trivial.假设\(A\)中有两个元素\(a, b\), ...
- LOJ2609. NOIP2013 火柴排队 【树状数组】
LOJ2609. NOIP2013 火柴排队 LINK 题目大意: 给你两个数列,定义权值∑i=1(ai−bi)^2 问最少的操作次数,最小化权值 首先需要发现几个性质 最小权值满足任意i,j不存在a ...
- [树状数组+逆序对][NOIP2013]火柴排队
火柴排队 题目描述 涵涵有两盒火柴,每盒装有n根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:∑ (ai-bi)2,i=1,2,3,. ...
- [NOIP2013] 火柴排队(归并排序)
题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...
- noip2013 火柴排队
题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...
随机推荐
- C++配置Opencv
https://blog.csdn.net/qq_17550379/article/details/78201442
- css3图书3D动画
css3图书3D动画,css3,立体特效,旋转效果,3D动画,css3图书3D动画是一款基于css3实现的立体旋转3D图书动画特效. 代码下载页:http://www.huiyi8.com/sc/71 ...
- 一步一步教你简单完成 Android USB开发
项目中有一个新的需求,要求可以连接一个USB体温枪,APP可以从体温枪中读取到体温数据,一番搜寻之后发现一个封装很棒的USB通信库. github地址:usb-serial-for-android 准 ...
- Go丨语言学习笔记--func
Java语言跟Go语言的函数比较 Go语言 func funcName(input type1,input type2,......)(output type1,output type2,...... ...
- JDK中主要的包介绍
- Vijos:P1234口袋的天空
背景 小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空. 有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖. 描述 给你云朵的个数N,再给你M个关系,表示哪些云朵可以连在一起. ...
- Oracle字段增删改方法总结
一.修改字段的语法:alter table tablename modify (字段名 类型 [default value][null/not null],….);有一个表名为tb,字段段名为name ...
- android和iOS平台的崩溃捕获和收集
转自:http://www.cnblogs.com/lancidie/archive/2013/04/13/3019349.html 通过崩溃捕获和收集,可以收集到已发布应用(游戏)的异常,以便开发人 ...
- Repeater 和 GridView 添加序列号
<tr><asp:Repeater ID="rptOfBrowerInfo" runat="server" > <Heade ...
- 【hdu2955】 Robberies 01背包
标签:01背包 hdu2955 http://acm.hdu.edu.cn/showproblem.php?pid=2955 题意:盗贼抢银行,给出n个银行,每个银行有一定的资金和抢劫后被抓的概率,在 ...