并查集+思维——Destroying Array
一、题目描述(题目链接)
给定一个序列,按指定的顺序逐一删掉,求连续子序列和的最大值。例如序列1 3 2 5,按3 4 1 2的顺序删除,即依次删除第3个、第4个、第1个、第2个,答案为5 4 3 0。
二、问题分析
我们知道从并查集中删除元素很难,而合并非常简单。所以我们可以反过来思考,正向删除元素等同于反向添加元素,将结果存起来反向输出即可。每次添加一个元素,更新最大值。很明显新加入的点只影响相邻元素的值。每添加一个元素有4种情况:单独成集合,只与前面的成集合,只与后面的成集合,既与前面的成集合又与后面的成集合。
三、代码实现
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdbool>
#include<algorithm>
using namespace std; typedef long long LL;
const int maxn = + ;
int n, A[maxn], B[maxn],fa[maxn];
bool vis[maxn];
LL res[maxn],sum[maxn]; void init()
{
for (int i = ; i <= n; i++)
{
sum[i] = A[i]; //sum[i]表示以i为根节点的集合的和
fa[i] = i;
}
} int findset(int x)
{
if (x != fa[x])
return fa[x] = findset(fa[x]);
return fa[x];
} void unite(int x, int y)
{
int rx = findset(x);
int ry = findset(y);
fa[rx] = ry;
sum[ry] += sum[rx]; //和也要合并
} int main()
{
scanf("%d", &n);
for (int i = ; i <= n; i++)
scanf("%d", &A[i]);
for (int i = ; i <= n; i++)
scanf("%d", &B[i]); init();
memset(vis, false, sizeof(vis));
int cnt = ;
LL maxx = ;
for (int i = n; i >= ; i--)
{
res[cnt++] = maxx;
int tmp = B[i];
if (tmp > && vis[tmp - ]) unite(tmp, tmp - ); //是否与前面相邻
if (tmp < n && vis[tmp + ]) unite(tmp, tmp + ); //是否与后面相邻
vis[tmp] = true;
maxx = max(maxx, sum[findset(tmp)]); //包括了单独成集合的情况
}
for (int i = cnt - ; i >= ; i--)
printf("%lld\n", res[i]);
return ;
}
并查集+思维——Destroying Array的更多相关文章
- F - Number of Connected Components UVALive - 7638 (并查集 + 思维)
题目链接:https://cn.vjudge.net/contest/275589#problem/F 题目大意:就是给你n个数,如果说两个数之间的gcd!=1,那么就将这两个点连起来,问你最终这些点 ...
- 并查集+思维——The Door Problem
一.问题描述(题目链接) 有n个门和m个开关,每个开关可以控制任意多的门,每个门严格的只有两个开关控制,问能否通过操作某些开关使得所有门都打开.(给出门的初始状态). 二.问题分析 大部分开关问题首先 ...
- 并查集+思维——X-Plosives
一.问题描述(题目链接) 有n种化合物,每种化合物由两种元素组成.当几种的化合物数量等于他们所含不同元素的数量时,就会发生爆炸.现在依次给出化合物的组成,当新的化合物与之前的化合物放在一起会发生爆炸时 ...
- [codeforces 859 E] Desk Disorder 解题报告 (并查集+思维)
题目链接:http://codeforces.com/problemset/problem/859/E 题目大意: 有$n$个人,$2n$个座位. 给出这$n$个人初始的座位,和他们想坐的座位. 每个 ...
- CodeForces - 763A(并查集/思维)
题意 https://vjudge.net/problem/CodeForces-763A 一棵无根树中各个节点被染上了一种颜色c[i] 现在让你选择一个点作为根节点,使得这个根节点的所有儿子满足以该 ...
- 79: cf 444E 并查集+思维
$des$ 题面 $sol$ 把边从小到大排序,枚举每条边作为答案,然后把两个点合并,判断每条边是否可以作为答案时,$cnt_i$ 表示节点 $i$ 已经合并的 $x$ 之和$size_i$ 表示已经 ...
- Codeforces Round #600 (Div. 2) D题【并查集+思维】
题意:给你n个点,m条边,然后让你使得这个这个图成为一个协和图,需要加几条边.协和图就是,如果两个点之间有一条边,那么左端点与这之间任意一个点之间都要有条边. 思路:通过并查集不断维护连通量的最大编号 ...
- 洛谷 P2391.白雪皑皑 (并查集,思维)
题意:有\(n\)个点,对这些点进行\(m\)次染色,第\(i\)次染色会把区间\((i*p+q)\ mod\ N+1\)和\((i*q+p)\ mod\ N+1\)之间的点染成颜色\(i\),问最后 ...
- B - Rikka with Graph HDU - 5631 (并查集+思维)
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some mat ...
随机推荐
- 4-3逻辑非运算符及案例 & 4-4
创建类 LoginDemo3 这里取反 !(n%3==0) package com.imooc.operator; import java.util.Scanner; public class Log ...
- JavaScript 对象字面量
JavaScript 对象字面量 JavaScript 对象字面量 在编程语言中,字面量是一种表示值的记法.例如,"Hello, World!" 在许多语言中都表示一个字符串字 ...
- [WIP]webpack 概念
创建: 2019/04/09 概念 入口 指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始. 进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖 ...
- HDU5918【KMP大法好,虽然我不会】
#include <bits/stdc++.h> using namespace std; typedef long long LL; const; int n,m; int a[MAX] ...
- CodeForces 689C【二分】
转自: http://blog.csdn.net/qq_26071477/article/details/51892995 #include<stdio.h> typedef long l ...
- laravel定义全局变量并输出(实例)
在config目录创建一个 bl.php ,内容如下 <?php return [ 'IND' => "1321232", 'das' => "奥术大师 ...
- std::thread 在DLLMain 中会发生死锁 std::thread cause deadlock in DLLMain
注意不要再DLLMain中使用 std::thread 否则会发生死锁. 但是可以使用 _beginthreadex (此函数可以使用lambda) 或者直接使用windows的底层函数: Creat ...
- 2014-10-23 NOIP模拟赛
NOIP2014模拟赛 -----lwher 时限均为1s,内存 256MB 1.Jams倒酒(pour) Jams是一家酒吧的老板,他的酒吧提供2种体积的啤酒,a ml 和 b ml,分别使用容积为 ...
- APP上传
原文网址: http://blog.csdn.net/ayangcool 前言:作为一名IOS开发者,把开发出来的App上传到App Store是必须的.下面就来详细介绍下具体流程. 1.打开苹果开发 ...
- Python scrapy框架爬取瓜子二手车信息数据
项目实施依赖: python,scrapy ,fiddler scrapy安装依赖的包: 可以到https://www.lfd.uci.edu/~gohlke/pythonlibs/ 下载 pywi ...