洛谷 P1966 火柴排队
2016-10-20 20:02
281 查看
题目描述
涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2
其中 ai 表示第一列火柴中第 i 个火柴的高度,bi 表示第二列火柴中第 i 个火柴的高度。
每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果。
【题目分析】
求逆序对。
【代码】
涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2
其中 ai 表示第一列火柴中第 i 个火柴的高度,bi 表示第二列火柴中第 i 个火柴的高度。
每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果。
【题目分析】
求逆序对。
【代码】
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int n,a[100001],la[100001],b[100001],lb[100001]; int c[100001],d[100001]; int t[100001],ans=0; const int mod=99999997; int read() { int ret=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9') { ret*=10; ret+=ch-'0'; ch=getchar(); } return ret*f; } void add(int x,int f) {for (;x<=n;x+=x&(-x)) t[x]+=f;} int gs(int x) { int ret=0; for (;x;x-=x&(-x)) ret+=t[x]; return ret; } int main() { scanf("%d",&n); for (int i=1;i<=n;++i) la[i]=a[i]=read(); sort(la+1,la+n+1); for (int i=1;i<=n;++i) a[i]=lower_bound(la+1,la+n+1,a[i])-la; for (int i=1;i<=n;++i) lb[i]=b[i]=read(); sort(lb+1,lb+n+1); for (int i=1;i<=n;++i) b[i]=lower_bound(lb+1,lb+n+1,b[i])-lb; for (int i=1;i<=n;++i) c[a[i]]=i; for (int i=1;i<=n;++i) d[i]=c[b[i]]; for (int i=1;i<=n;++i) { add(d[i],1); (ans+=gs(n)-gs(d[i]))%=mod; } printf("%d\n",ans); }
相关文章推荐
- [NOIP2013提高&洛谷P1966]火柴排队 题解(树状数组求逆序对)
- 洛谷 P1966 火柴排队
- 洛谷 P1966 [NOIP2013 D1T2] 火柴排队
- 洛谷——P1966 火柴排队
- Codevs 3286&&洛谷 P1966 火柴排队
- 【洛谷】P1966 火柴排队
- P1966 火柴排队
- P1966 火柴排队
- 洛谷1966 火柴排队
- 洛谷 1966 [NOIP2013] 火柴排队 逆序对
- P1966 火柴排队
- 洛谷1966 火柴排队
- [luogu]P1966火柴排队-逆序对与归并排序的初步运用
- 【codevs 3286】火柴排队
- Codevs 火柴排队
- 洛谷p1966 火柴排队 (逆序对变形,目标排序
- rqnoj(PID737 / 火柴排队 match)
- 【NOIP2013提高组day1】火柴排队
- NOIP2013 火柴排队 解题报告(贪心+逆序对)
- 火柴排队