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 }
  • 相关阅读:
    error: expected unqualified-id extern "C" {
    cmake交叉编译android(转)
    wwindows文件放入linux后多出换行符
    JNI 引用问题梳理(转)
    OpenCV实现任意大小图片的合并(转)
    android camera preview常用格式
    Linux下找不到动态链接库(转)
    ld链接器的工作原理及链接顺序(转)
    添加静态库入动态库时,符号查找不到的问题
    如何捕获 System.loadLibrary 产生的异常?(转)
  • 原文地址:https://www.cnblogs.com/lfri/p/9484427.html
Copyright © 2011-2022 走看看