P3531 [POI2012]LIT-Letters(求逆序对)
题目传送门:https://www.luogu.com.cn/problem/P3531
题意
给出只包含大写字母的字符串 A 和字符串 B,每次可以交换字符串 A 两个相邻的字符,求 A 变成 B 的最小交换次数。
思路
这道题给了我一丝熟悉感,就像给定一个数组,我们每次可以交换数组中相邻的两个元素,求将它变成有序需要的最小的交互次数,也就是求其逆序对个数。其实它们的运作方式是完全,只不过这里只是将“有序”的基准变成了 “变成 B”。
如果字符串中的字符无法让我们直接完成求解操作,我们需要先利用下标进行一个转换操作。以下面这组用例为例:
4
CABC
CCAB
我们先对 A 编号,并按字符提取下标:
1 2 3 4
C A B C
=>
A: 2
B: 3
C: 1 4
接着,我们根据提取的下标对字符串 B 进行编号:
C C A B
=>
1 4 2 3
最后,我们可以通过对数列 1 4 2 3
求逆序对得到答案啦~
参考代码
求逆序对常用的方法有两种,一种是归并排序,在合并的时候用 ans += mid - i + 1
进行求解;另一种是树状数组,遍历数组时用ans += i - sum(a[i])
求解。
1. 归并排序
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 1e6 + 10;
long long ans, n;
// lt[i]表示字母(i+'A')访问到st[i]的下标
// a[] 表示处理之后元素值各不相同的数组,temp[] 是归并过程中用到的中间数组
int lt[26], a[maxn], temp[maxn];
vector<int> st[26]; // st[i][j] 表示第j个字母(i+'A')所在的下标
string strA, strB;void mergeSort(int left, int right) {if (left == right) {return ;}int mid = left + (right - left) / 2;int i = left, j = mid + 1, k = left;mergeSort(left, mid);mergeSort(mid + 1, right);while (i <= mid && j <= right) {if (a[i] <= a[j]) {temp[k++] = a[i++];} else {temp[k++] = a[j++];ans += mid - i + 1; // 求逆序对}}while (i <= mid) {temp[k++] = a[i++];}while (j <= right) {temp[k++] = a[j++];}for (int l = left; l <= right; l++) {a[l] = temp[l];}
}int main()
{cin >> n;cin >> strA >> strB;for (int i = 0; i < n; i++) {int idx = strA[i] - 'A';st[idx].push_back(i + 1);}for (int i = 0; i < n; i++) {int idx = strB[i] - 'A';a[i + 1] = st[idx][lt[idx]++];}mergeSort(1, n);cout << ans << endl;return 0;
}
2. 树状数组
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 1e6 + 10;
long long ans, n;
// lt[i]表示字母(i+'A')访问到st[i]的下标
// a[] 表示处理之后元素值各不相同的数组,temp[] 是归并过程中用到的中间数组
int lt[26], a[maxn], c[maxn];
vector<int> st[26]; // st[i][j] 表示第j个字母(i+'A')所在的下标
string strA, strB;int lowbit(int x) {return x & (-x);
}void update(int i, int x) {for ( ; i <= n; i += lowbit(i))c[i] += x;
}int sum(int i) {int res = 0;for ( ; i >= 1; i -= lowbit(i))res += c[i];return res;
}int main()
{cin >> n;cin >> strA >> strB;for (int i = 0; i < n; i++) {int idx = strA[i] - 'A';st[idx].push_back(i + 1);}for (int i = 0; i < n; i++) {int idx = strB[i] - 'A';a[i + 1] = st[idx][lt[idx]++];}for (int i = 1; i <= n; i++) {update(a[i], 1);ans += i - sum(a[i]); // 求逆序对}cout << ans << endl;return 0;
}
P3531 [POI2012]LIT-Letters(求逆序对)相关推荐
- szu 寒训第二天 树状数组 二维树状数组详解,以及树状数组扩展应用【求逆序对,以及动态第k小数】
树状数组(Binary Index Tree) 树状数组可以解决可以转化为前缀和问题的问题 这是一类用以解决动态前缀和的问题 (有点像线段树简版) 1.对于 a1 + a2 + a3 + - + an ...
- Tido 习题-二叉树-树状数组求逆序对
这里给大家提供一个全新的求逆序对的方法 是通过树状数组来实现的 题目描述 样例输入 Copy 5 2 3 1 5 4 样例输出 Copy 3 提示 #include<iostre ...
- codevs1688 求逆序对(权值线段树)
1688 求逆序对 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 给定一个序列a1,a2,-,an,如 ...
- 归并排序模板(附求逆序对)
逆序对满足两个条件, i < j 和 ai > aj 归并可以求逆序对, 因为是按顺序加入, 所以右区间加入的时候, 左区间的数满足 i < j, 然后左边还没有加入的数肯定比当前的 ...
- hust1347(归并排序求逆序对)
题意: 给出一个数列,你要对这个数列的数字进行k次交换操作,使得交换之后的数列逆序对虽少. 思路: 求原数列的逆序对,再和k比就行了.求逆序对要用归并排序,因为树状数组开不下. 代码: #includ ...
- 树状数组求逆序对_区间和的个数(树状数组)
327. 区间和的个数 给定一个整数数组 nums,返回区间和在 [lower, upper] 之间的个数,包含 lower 和 upper. 区间和 S(i, j) 表示在 nums 中,位置从 i ...
- 用不同的姿势求逆序对(复习篇)
用不同的姿势求逆序对(复习篇) 文章目录 用不同的姿势求逆序对(复习篇) 前言 讲解 归并排序 树状数组 线段树 题目 思路 代码 归并排序求逆序对 树状数组求逆序对 线段树求逆序对 历届试题 小朋友 ...
- CodeForces - 1417E XOR Inverse(字典树求逆序对+分治)
题目链接:点击查看 题目大意:给出一个长度为 n 的数列 a,现在要求选出一个 x,将 a 中的每个元素都异或之后得到一个新的数列 b,要求数列 b 的逆序对最小,问最小的逆序对是多少,x 该如何选择 ...
- 信息竞赛进阶指南--归并排序求逆序对
// 归并排序求逆序对 void merge(int l, int mid, int r) {// 合并a[l~mid]与a[mid+1~r]// a是待排序数组, b是临时数组, cnt是逆序对个数 ...
最新文章
- 面试都在问的微服务,一文带你彻底搞懂!
- Android中文API(115)——AudioFormat
- matlab input函数学习
- 中国油气装备行业发展状况与投资前景咨询报告2022-2028年版
- N-Gram的数据结构
- Kudu1.1.0 、 Kudu1.2.0 Kudu1.3.0的版本信息异同比较
- Python(18)-字典dictionary、集合
- php自定义tcp协议,如何实现自定义协议?
- win10鼠标指针修改
- c语言交通处罚管理系统刘,交通处罚单管理系统(C程序设计)修改版
- 【写博客常用】Word文档中怎么插入分隔线
- 计算机配件价格上涨,显卡涨价风声再起 PC配件涨价什么时候是个头
- ybt1373 鱼塘钓鱼
- 基于aspect的情感分析综述 论文翻译笔记 A Survey on Aspect-Based Sentiment Analysis: Tasks, Methods, and Challenges
- 谷歌是如何以简洁赢取用户的
- windows 调试若干知识
- React Native与原生的图片交互问题
- IxEngine开发笔记
- Python3的桌面程序开发利器:Eric6的环境搭建、使用
- 位图文件, JPG格式,PNG格式
热门文章
- [architecture]-Armv8 Cryptographic Extension介绍
- 使用 ZwUnmapViewOfSection 卸载并替换内存镜像
- 深入分析H2数据库控制台中无需身份验证的RCE漏洞
- 别再问Cloudflare CDN 漏洞是怎么被利用的啦!这篇文就来告诉你
- 透露抖音、腾讯、阿里、美团招开发岗位硬核面试题,轻轻松松收到offer
- 【PAT乙级】1082 射击比赛 (20 分)
- 【PAT乙级】1047 编程团体赛 (20 分)
- ActiveMQ介绍
- Java的List遍历
- python最大分词_python正向最大匹配分词和逆向最大匹配分词的实例