本文連接: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 }