并查集+思维——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\n", res[i]); 61 return 0; 62 }
转载于:https://www.cnblogs.com/lfri/p/9484427.html
并查集+思维——Destroying Array相关推荐
- CodeForces - 468B Two Sets(并查集+思维)
题目链接:点击查看 题目大意:现在给出两个集合A和B,再给出两个数a和b,现在规定在集合A中的数x必须满足x和a-x同时在集合a中,而在集合B中的数x也同样需要满足x和b-x同时在集合B中,现在给出一 ...
- All men are brothers(并查集+思维 好题!!!)
链接:https://ac.nowcoder.com/acm/contest/889/E 来源:牛客网 Amy asks Mr. B problem E. Please help Mr. B to s ...
- gym:Problem A Artwork(并查集思维题)
20162017-acmicpc-nordic-collegiate-programming-contest-ncpc-2016 Problem A Artwork 题目链接 http://codef ...
- 2020牛客暑期多校训练营(第八场)I-Interesting Computer Game(并查集 + 思维)
链接: I-Interesting Computer Game 题意: 给出 n 组 a,b,每次可以选择 a 或者选择 b ,问做多可以选多少个不同的数. 思路: 考虑每个连通块 , 如果是 n 个 ...
- Codeforces 200A Cinema 并查集 + 思维 (看题解)
Cinema 感觉这个题好神啊... 首先如果 n 比 m 大, 我们先旋转90度. 我们要加入一个(x, y)的时候, 我们枚举答案所在的行离 x 的距离 g , 然后对于x + g 行来说 我们找 ...
- upc 潜入苏拉玛 多源bfs + 并查集 + 思维
潜入苏拉玛 时间限制: 1 Sec 内存限制: 128 MB 题目描述 你接到了⼀个任务,让你潜⼊苏拉玛城,和线⼈取得联络.苏拉玛的地图是⼀张N个点M条边的⽆向图,每个点表⽰苏拉玛城的⼀个路⼜,每条边 ...
- 小希的迷宫 HDU - 1272---并查集+思维
上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了 ...
- P1892 [BOI2003]团伙 +食物链 POJ - 1182 (并查集+思维)
思路①: 开数组enem[i]记录节点i的敌对节点,当再次输入i的敌对节点时就把他所在并查集的根节点和enem[i]并起来. #include<bits/stdc++.h> using n ...
- codeforces1012 B. Chemical table(并查集+思维)
B. Chemical table One of the way to solve this problem is to interprete the cells in 2d matrix as an ...
最新文章
- 利用sendEmail-v1.55转发邮件
- java基础系列:集合总结(4)
- java中以json形式的打印
- HDU 1180 诡异的楼梯(超级经典的bfs之一,需多回顾)
- Java可能使用UTF-8作为其默认字符集
- 殷浩详解DDD:如何避免写流水账代码?
- java size_Java length() 方法,length 属性和 size() 方法的区别
- 使用jupyterthemes插件定制jupyter notebook界面
- Linux下C++ Socket编程实例
- oracle instant client 32,Oracle Instant Client 配置方法
- 免費工具 - PDF转换成Flipbook, 并把它放在漂亮的书架上
- 开机自启动并关闭窗口(向日葵简约版)
- Arduino控制PS2无线手柄
- 电脑重装系统不小心格式化了恢复文件教程
- 从零双排java之打印流
- Wireshark使用技巧之GeoIP显示IP地理位置及经纬度信息
- 温度PID的整定过程
- (c语言) 计算油费
- PythonC++相互混合调用编程全面实战-03ctypes类型对应
- 【项目二、蜂巢检测项目】一、串讲各类经典的卷积网络:InceptionV1-V4、ResNetV1-V2、MobileNetV1-V3、ShuffleNetV1-V2、ResNeXt、Xception