題意:給你和一個數組(是一個排列)和一些二元組,二元組(x, y)表示如果x正好在y前面而且相鄰,那么x和y可以交換位置,問最后一個元素最多可以向前移動多少步?
思路:對於每個數,有兩種選擇,一種是向后走,一種是向前走。假設我們決定讓這個數向前走,那么把所有以它結尾的二元組的cnt加1。cnt代表的是后面有多少個數可以與這個數合並。假設當前位置是i,若n - i - ans == cnt[i],說明這個數可以與最后一個數合並,ans加1。因為若滿足這個等式,說明存在一種方法,讓最后一個數恰好與i交換成功一次。
代碼:
#include <bits/stdc++.h>
#define LL long long
#define lowbit(x) (x & (-x))
#define pii pair<int, int>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 300010;
int cnt[maxn];
vector<int> c[maxn];
int a[maxn];
int main() {
int n, m, x, y;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= m; i++) {
scanf("%d%d", &x, &y);
c[y].push_back(x);
}
for (int i = 0; i < c[a[n]].size(); i++)
cnt[c[a[n]][i]]++;
int ans = 0;
for (int i = n - 1; i >= 1; i--) {
if(n - i - ans == cnt[a[i]]) ans++;
else {
for (int j = 0; j < c[a[i]].size(); j++)
cnt[c[a[i]][j]]++;
}
}
printf("%d\n", ans);
}
---恢復內容結束---
