題意:給你和一個數組(是一個排列)和一些二元組,二元組(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); }
---恢復內容結束---