• Codeforces 722C(并查集 + 思维)


    本文链接:http://www.cnblogs.com/Ash-ly/p/5932712.html

    题目链接:http://codeforces.com/problemset/problem/722/C

    思路:

      题目给的操作数从第 1 个到第 N 个数是删除原数组中的一个数, 那么反过来从后往前就是增加原数组中的一个数, 每增加一个值, 那么就有四种情况: 第一种和前后都不连续, 即自成一个集合; 第二种:和前面的数连续, 即和前一个数在一个集合; 第三种和之后一个数连续, 即和之后的一个数在一个集合; 第四种既和前面一个数连续也和后面一个数连续,那么说明前后两个集合被这个数合并成一个集合. 然后合并的时候维护每个集合的元素和 sum, 利用 max 记录当前集合 sum 和新增集合的 sum 中的最大值.

    代码:

     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 }
  • 相关阅读:
    ADO.NET 之 二 yz
    ADO.NET 之 三 yz
    telerik的RadAutoCompleteBox控件学习完结 yz
    ADO.NET 之 三 2 yz
    ASP.NET 底层技术 一 yz
    telerik的RadAutoCompleteBox控件学习三 yz
    ASP.NET 之 自定义 异步HTTP处理程序 yz
    javascriptArray类型 二 yz
    telerik的RadAutoCompleteBox控件学习一 yz
    javascript——Array类型 yz
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5932712.html
Copyright © 2020-2023  润新知