C. Tokitsukaze and Two Colorful Tapes_並查集+環
阿新 • • 發佈:2022-05-13
C. Tokitsukaze and Two Colorful Tapes_並查集+環
題目大意
給ab兩個陣列,他們均是n的排列。現在要在滿足原來ai==bj的仍舊相等的條件下,重新排列ab,使得sum(abs(ai-bi))最大。
思路和程式碼
比較好看的就是這是一堆環。我們貪心的去給每個環一大一小的去分配數字即可。要注意其實奇數環和偶數環是一樣的。如下圖中只要把點5拿掉即可。
struct dsu{ vct<int> fa ; dsu(int n){ fa.resize(n + 1) ; rep(i , 0 , fa.size() - 1) fa[i] = i ; } int find(int u){ return fa[u] == u ? u : find(fa[u]) ; } void merge(int u , int v){ fa[find(u)] = find(v) ; } }; int n , m , k ; void solve(){ cin >> n ; dsu d(n) ; map<int , int> mp ;//維護環尺寸 vct<int> a(n + 1 , 0) ; vct<int> b(n + 1 , 0) ; rep(i , 1 , n) cin >> a[i] ; rep(i , 1 , n) cin >> b[i] ; rep(i , 1 , n) d.merge(a[i] , b[i]) ; rep(i , 1 , n) mp[d.find(i)] ++ ; ll ans = 0 ; vct<ll> p(n + 1 , 0) ; rep(i , 1 , n) p[i] = p[i - 1] + i ; ll l = 1 , r = n ; for(auto node : mp){ int cnt = node.se ; if(cnt == 1) continue ; // cout << cnt << "\n" ; int l2 = l + cnt / 2 - 1 ; int r2 = r - cnt / 2 + 1 ; ans += 2 * ((p[r] - p[r2 - 1]) - (p[l2] - p[l - 1])) ; l = l2 + 1 , r = r2 - 1 ; } cout << ans << "\n" ; }//code_by_tyrii
小結
和這題很像