zoukankan      html  css  js  c++  java
  • 并查集+思维——Destroying Array

    一、题目描述(题目链接)

    给定一个序列,按指定的顺序逐一删掉,求连续子序列和的最大值。例如序列1 3 2 5,按3 4 1 2的顺序删除,即依次删除第3个、第4个、第1个、第2个,答案为5 4 3 0。

    二、问题分析

    我们知道从并查集中删除元素很难,而合并非常简单。所以我们可以反过来思考,正向删除元素等同于反向添加元素,将结果存起来反向输出即可。每次添加一个元素,更新最大值。很明显新加入的点只影响相邻元素的值。每添加一个元素有4种情况:单独成集合,只与前面的成集合,只与后面的成集合,既与前面的成集合又与后面的成集合。

    三、代码实现

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdbool>
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 typedef long long LL;
     9 const int maxn = 100000 + 10;
    10 int n, A[maxn], B[maxn],fa[maxn];
    11 bool vis[maxn];
    12 LL res[maxn],sum[maxn];
    13 
    14 void init()
    15 {
    16     for (int i = 1; i <= n; i++)
    17     {
    18         sum[i] = A[i];    //sum[i]表示以i为根节点的集合的和
    19         fa[i] = i;
    20     }
    21 }
    22 
    23 int findset(int x)
    24 {
    25     if (x != fa[x])
    26         return  fa[x] = findset(fa[x]);
    27     return fa[x];
    28 }
    29 
    30 void unite(int x, int y)
    31 {
    32     int rx = findset(x);
    33     int ry = findset(y);
    34     fa[rx] = ry;
    35     sum[ry] += sum[rx];        //和也要合并
    36 }
    37 
    38 int main()
    39 {
    40     scanf("%d", &n);
    41     for (int i = 1; i <= n; i++)
    42         scanf("%d", &A[i]);
    43     for (int i = 1; i <= n; i++)
    44         scanf("%d", &B[i]);
    45 
    46     init();
    47     memset(vis, false, sizeof(vis));
    48     int cnt = 0;
    49     LL maxx = 0;
    50     for (int i = n; i >= 1; i--)
    51     {
    52         res[cnt++] = maxx;
    53         int tmp = B[i];
    54         if (tmp > 1 && vis[tmp - 1])    unite(tmp, tmp - 1);    //是否与前面相邻
    55         if (tmp < n && vis[tmp + 1])    unite(tmp, tmp + 1);    //是否与后面相邻
    56         vis[tmp] = true;
    57         maxx = max(maxx, sum[findset(tmp)]);    //包括了单独成集合的情况
    58     }
    59     for (int i = cnt - 1; i >= 0; i--)
    60         printf("%lld
    ", res[i]);
    61     return 0;
    62 }
  • 相关阅读:
    eclipse+maven springMVC搭建
    mac下搭建eclipse+git环境并导入项目
    mvn deploy返回400错误的几种可能
    vector的坑——C++primer练习6.33总结
    2015/4/8腾讯笔试
    ColKang v1.0
    C++学习——C++复合类型
    朴素贝叶斯文本分类-在《红楼梦》作者鉴别的应用上(python实现)
    python:BeautifulSoup学习
    python:网络爬虫的学习笔记
  • 原文地址:https://www.cnblogs.com/lfri/p/9484427.html
Copyright © 2011-2022 走看看