Codeforces 722C(並查集 + 思惟)

本文連接:http://www.cnblogs.com/Ash-ly/p/5932712.htmlhtml

題目連接:http://codeforces.com/problemset/problem/722/Cios

思路:c++

  題目給的操做數從第 1 個到第 N 個數是刪除原數組中的一個數, 那麼反過來從後往前就是增長原數組中的一個數, 每增長一個值, 那麼就有四種狀況: 第一種和先後都不連續, 即自成一個集合; 第二種:和前面的數連續, 即和前一個數在一個集合; 第三種和以後一個數連續, 即和以後的一個數在一個集合; 第四種既和前面一個數連續也和後面一個數連續,那麼說明先後兩個集合被這個數合併成一個集合. 而後合併的時候維護每一個集合的元素和 sum, 利用 max 記錄當前集合 sum 和新增集合的 sum 中的最大值.數組

代碼:spa

 1 #include <bits/stdc++.h>
 2 
 3 typedef long long LL;
 4 const int MAXN = 100000;
 5 using namespace std;
 6 LL pre[MAXN + 3], cnt[MAXN + 3], a[MAXN + 3], pos[MAXN + 3], visit[MAXN + 3], ans[MAXN + 3];
 7 
 8 int Find(int x) { return x == pre[x] ? x : pre[x] = Find(pre[x]); }
 9 
10 void mix(int x, int y) {
11     int fx = Find(x), fy = Find(y);
12     if(fx != fy) pre[fy] = fx, cnt[fx] += cnt[fy]; //合併兩個集合的同時維護新集合的 sum
13 }
14 
15 int main() {
16     ios_base::sync_with_stdio(0); cin.tie();
17     int n; cin >> n;
18     for(int i = 1; i <= n; i++) {
19         cin >> a[i];
20         pre[i] = i, visit[i] = 0;
21     }
22     for(int i = 0; i < n; i++) cin >> pos[i];
23     LL maxn = 0;
24     for(int i = n - 1; i >= 0; i--) {
25         int tp = pos[i];
26         cnt[tp] = a[tp], visit[tp] = 1, ans[i] = maxn;
27         if(tp != 1 && visit[tp - 1]) mix(tp, tp - 1); // 新增一個元素後造成的四種狀況
28         if(tp != n && visit[tp + 1]) mix(tp, tp + 1);
29         maxn = max(maxn, cnt[ Find(tp) ]);
30     }
31     for(int i = 0; i < n; i++) cout << ans[i] << endl;
32     return 0;
33 }
相關文章
相關標籤/搜索