题意

题目链接

Sol

不算很难的一道题

首先要保证权值最小,不难想到一种贪心策略,即把两个序列中rank相同的数放到同一个位置

证明也比较trivial。假设\(A\)中有两个元素\(a, b\),\(B\)中有两个元素\(c, d\)

然后分别讨论一下当\(a < b\)时\(c\)与\(a\)对应优还是与\(b\)对应优。

化简的时候直接对两个式子做差。

这样我们找到第二个序列中的每个数应该排到哪个位置,树状数组求一下逆序对就行了。

#include<bits/stdc++.h>
#define lb(x) (x & -x)
#define Fin(x) {freopen(#x".in", "r", stdin);}
using namespace std;
const int MAXN = 1e5 + 10, mod = 99999997;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, a[MAXN], b[MAXN], pos[MAXN], rak[MAXN], date[MAXN], T[MAXN];
void Get(int *a) {
memcpy(date, a, sizeof(a) * (N + 1));
sort(date + 1, date + N + 1);
int num = unique(date + 1, date + N + 1) - date - 1;
for(int i = 1; i <= N; i++) a[i] = lower_bound(date + 1, date + num + 1, a[i]) - date;
}
void Add(int x, int val) {
while(x <= N) T[x] += val, x += lb(x);
}
int Query(int pos) {
int ans = 0;
while(pos) ans += T[pos], pos -= lb(pos);
return ans;
}
int add(int x, int y) {
if(x + y < 0) return x + y + mod;
else return (x + y >= mod) ? x + y - mod : x + y;
}
signed main() {
N = read();
for(int i = 1; i <= N; i++) a[i] = read();
for(int i = 1; i <= N; i++) b[i] = read();
Get(a); Get(b);
for(int i = 1; i <= N; i++) pos[a[i]] = i;
for(int i = 1; i <= N; i++) rak[i] = pos[b[i]];
int ans = 0;
for(int i = 1; i <= N; i++)
Add(rak[i], 1), ans = add(ans, i - Query(rak[i]));
printf("%d", ans);
return 0;
}

洛谷P1966 火柴排队(逆序对)的更多相关文章

  1. [NOIP2013提高&洛谷P1966]火柴排队 题解(树状数组求逆序对)

    [NOIP2013提高&洛谷P1966]火柴排队 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相 ...

  2. 【刷题】洛谷 P1966 火柴排队

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

  3. 洛谷 P1966 火柴排队 解题报告

    P1966 火柴排队 题目描述 涵涵有两盒火柴,每盒装有 \(n\) 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: \(\s ...

  4. luogu P1966 火柴排队 (逆序对)

    luogu P1966 火柴排队 题目链接:https://www.luogu.org/problemnew/show/P1966 显然贪心的想,排名一样的数相减是最优的. 证明也很简单. 此处就不证 ...

  5. 洛谷——P1966 火柴排队&&P1774 最接近神的人_NOI导刊2010提高(02)

    P1966 火柴排队 这题贪心显然,即将两序列中第k大的数的位置保持一致,证明略: 树状数组求逆序对啦 浅谈树状数组求逆序对及离散化的几种方式及应用 方法:从前向后每次将数插入到bit(树状数组)中, ...

  6. P1966 火柴排队——逆序对(归并,树状数组)

    P1966 火柴排队 很好的逆序对板子题: 求的是(x1-x2)*(x1-x2)的最小值: x1*x1+x2*x2-2*x1*x2 让x1*x2最大即可: 可以证明将b,c数组排序后,一一对应的状态是 ...

  7. P1966 火柴排队(逆序对)

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

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

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

  9. NOIP 2013 洛谷P1966 火柴排队 (树状数组求逆序对)

    对于a[],b[]两个数组,我们应选取其中一个为基准,再运用树状数组求逆序对的方法就行了. 大佬博客:https://www.cnblogs.com/luckyblock/p/11482130.htm ...

随机推荐

  1. iOS导入c++语言的静态库之后编译不过,先要检查是否导入了libstdc++

    iOS项目中引入c++库,编译链接时报如下错: "std::string::_Rep::_M_destroy(std::allocator<char> const&)&q ...

  2. SQL 判断Null

    字段 is null 这是多久没写SQL 了啊....................

  3. php 常用字符集

    ASCII 字符集 单字节编码,7位(bits)表示一个字符,共128字符 包含内容 控制字符:回车键.退格.换行键等. 可显示字符:英文大小写字符.阿拉伯数字和西文符号 ANSI 码  ANSI编码 ...

  4. Hero

    Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Description When pl ...

  5. c# 委托访问listbox多线程操作

    c# 委托访问listbox多线程操作 using System;using System.Collections.Generic;using System.ComponentModel;using ...

  6. LOJ6519. 魔力环(莫比乌斯反演+生成函数)

    题目链接 https://loj.ac/problem/6519 题解 这里给出的解法基于莫比乌斯反演.可以用群论计数的相关方法代替莫比乌斯反演,但两种方法的核心部分是一样的. 环计数的常见套路就是将 ...

  7. 页面加载时的div动画

    用@keyframes(动画),实现页面加载时的div动画(不要用js控制,因为当页面加载的时候,js还不一定可以使用) 可以在https://daneden.github.io/animate.cs ...

  8. G: 又见模法师

    G: 又见模法师 Time Limit: 1 s      Memory Limit: 128 MB        #include <stdio.h> ; typedef long lo ...

  9. shell编程下

    第1章 Whicle 1.1 while循环语句 在编程语言中,while循环(英语:while loop)是一种控制流程的陈述.利用一个返回结果为布林值(Boolean)的表达式作为循环条件,当这个 ...

  10. DOC窗口之cd命令(windows)

    cd的全称是Change Directory,改变文件夹,也就是切换路径.后面可以接驱动器符号.完整路径和相对路径. 通常win+R,输入cmd,便会看到以下界面, 通常,这个命令下并没有我们想要处理 ...