日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

P3531 [POI2012]LIT-Letters(求逆序对)

發(fā)布時間:2025/3/20 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P3531 [POI2012]LIT-Letters(求逆序对) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目傳送門:https://www.luogu.com.cn/problem/P3531

題意

給出只包含大寫字母的字符串 A 和字符串 B,每次可以交換字符串 A 兩個相鄰的字符,求 A 變成 B 的最小交換次數(shù)。

思路

這道題給了我一絲熟悉感,就像給定一個數(shù)組,我們每次可以交換數(shù)組中相鄰的兩個元素,求將它變成有序需要的最小的交互次數(shù),也就是求其逆序?qū)€數(shù)。其實它們的運作方式是完全,只不過這里只是將“有序”的基準變成了 “變成 B”。

如果字符串中的字符無法讓我們直接完成求解操作,我們需要先利用下標進行一個轉(zhuǎn)換操作。以下面這組用例為例:

4 CABC CCAB

我們先對 A 編號,并按字符提取下標:

1 2 3 4 C A B C => A: 2 B: 3 C: 1 4

接著,我們根據(jù)提取的下標對字符串 B 進行編號:

C C A B => 1 4 2 3

最后,我們可以通過對數(shù)列 1 4 2 3 求逆序?qū)Φ玫酱鸢咐瞺

參考代碼

求逆序?qū)ΤS玫姆椒ㄓ袃煞N,一種是歸并排序,在合并的時候用 ans += mid - i + 1 進行求解;另一種是樹狀數(shù)組,遍歷數(shù)組時用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[] 表示處理之后元素值各不相同的數(shù)組,temp[] 是歸并過程中用到的中間數(shù)組 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; // 求逆序?qū)?/span>}}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. 樹狀數(shù)組

#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[] 表示處理之后元素值各不相同的數(shù)組,temp[] 是歸并過程中用到的中間數(shù)組 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]); // 求逆序?qū)?/span>}cout << ans << endl;return 0; }

總結(jié)

以上是生活随笔為你收集整理的P3531 [POI2012]LIT-Letters(求逆序对)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。