原题中需要求解的是按照它给定的操作次序,即每次删掉一个数字求删掉后每个区间段的和的最大值是多少。
  正面求解需要维护新形成的区间段,以及每段和,需要一些数据结构比如 map 和 set。 map<int, LL>interval2Sum来维护区间段(u->v),mulitset<LL>sum 来维护最大值。那么每次删除操作后,都需要去interval2Sum中找到对应区间,然后erase掉,
重新生成left -> delId -> right两个区间段,最后在maxSum中删掉原有的sum值 ,加入新形成的两短sum。正面刚的话,因为map 和 set的高效性 log级别所以速度还是不错的。(代码转自Codeforces : Ra16bit)
  

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int n,i,a,le,ri;
  4. long long s[];
  5. map<int, long long> all;
  6. multiset<long long> sum;
  7. int main() {
  8. scanf("%d",&n);
  9. for (i=; i<=n; i++) {
  10. scanf("%d",&a);
  11. s[i]=s[i-]+a;
  12. }
  13. all[]=n;
  14. sum.insert(-s[n]);
  15. for (i=; i<=n; i++) {
  16. scanf("%d",&a);
  17. auto it=all.lower_bound(a);
  18. it--;
  19. le=it->first;
  20. ri=it->second;
  21. sum.erase(sum.find(s[le]-s[ri]));
  22. all.erase(it);
  23. if (le+<a) {
  24. all[le]=a-;
  25. sum.insert(s[le]-s[a-]);
  26. }
  27. if (a<ri) {
  28. all[a]=ri;
  29. sum.insert(s[a]-s[ri]);
  30. }
  31. if (i==n) puts(""); else printf("%I64d\n",-*sum.begin());
  32. }
  33. return ;
  34. }

  反向思路,从删掉了最后一个元素开始。一个个恢复。判断左右是否有已经恢复的元素然后在区间内归并元素,用并查集来判断区间所属。那么区间段值不断增大,最后得到结果。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <vector>
  5. #define LL long long
  6. using namespace std;
  7.  
  8. const int Maxn = ;
  9. int n, delId[Maxn], par[Maxn], used[Maxn];
  10. LL a[Maxn], b[Maxn], ans[Maxn];
  11.  
  12. int find(int x)
  13. {
  14. return (par[x] == x)?x: find(par[x]);
  15. }
  16.  
  17. int main()
  18. {
  19. cin>>n;
  20. for(int i = ; i < n; i ++){
  21. scanf("%lld",&a[i]);
  22. par[i] = i;
  23. used[i] = ;
  24. }for(int i = ; i < n; i ++){
  25. scanf("%d",&delId[i]);
  26. delId[i] --;
  27. }
  28. for(int i = n - ; i >= ; i --){
  29. int index = delId[i];
  30. used[index] = ;
  31. b[index] += a[index];
  32. if(used[index - ] && index){
  33. int fa = find(index - );
  34. b[fa] += a[index];
  35. par[index] = fa;
  36. }if(used[index + ] && index != n - ){
  37. int newFa = find(index), oldFa = find(index + );
  38. par[oldFa] = newFa;
  39. b[newFa] += b[oldFa];
  40. }
  41. ans[i] = max(ans[i + ], b[find(index)]);
  42. }
  43. for(int i = ; i <= n; i ++){
  44. cout<<ans[i]<<" ";
  45. }cout<<endl;
  46. return ;
  47. }
C. Destroying Array
time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an array consisting of n non-negative integers a1, a2, ..., an.

You are going to destroy integers in the array one by one. Thus, you are given the permutation of integers from 1 to n defining the order elements of the array are destroyed.

After each element is destroyed you have to find out the segment of the array, such that it contains no destroyed elements and the sum of its elements is maximum possible. The sum of elements in the empty segment is considered to be 0.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the length of the array.

The second line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 109).

The third line contains a permutation of integers from 1 to n — the order used to destroy elements.

Output

Print n lines. The i-th line should contain a single integer — the maximum possible sum of elements on the segment containing no destroyed elements, after first i operations are performed.

Examples
input
  1. 4
    1 3 2 5
    3 4 1 2
output
  1. 5
    4
    3
    0
input
  1. 5
    1 2 3 4 5
    4 2 3 5 1
output
  1. 6
    5
    5
    1
    0
input
  1. 8
    5 5 4 4 6 6 5 5
    5 2 8 7 1 3 4 6
output
  1. 18
    16
    11
    8
    8
    6
    6
    0
Note

Consider the first sample:

  1. Third element is destroyed. Array is now 1 3  *  5. Segment with maximum sum 5 consists of one integer 5.
  2. Fourth element is destroyed. Array is now 1 3  *   * . Segment with maximum sum 4 consists of two integers 1 3.
  3. First element is destroyed. Array is now  *  3  *   * . Segment with maximum sum 3 consists of one integer 3.
  4. Last element is destroyed. At this moment there are no valid nonempty segments left in this array, so the answer is equal to 0.

Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C. Destroying Array -- 逆向思维的更多相关文章

  1. Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) A B C D 水 模拟 并查集 优先队列

    A. Broken Clock time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  2. Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) B. Verse Pattern 水题

    B. Verse Pattern 题目连接: http://codeforces.com/contest/722/problem/B Description You are given a text ...

  3. Intel Code Challenge Elimination Round (Div.1 + Div.2, combined)

    A. Broken Clock time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  4. Intel Code Challenge Elimination Round (Div.1 + Div.2, combined)(set容器里count函数以及加强for循环)

    题目链接:http://codeforces.com/contest/722/problem/D 1 #include <bits/stdc++.h> #include <iostr ...

  5. 二分 Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) D

    http://codeforces.com/contest/722/problem/D 题目大意:给你一个没有重复元素的Y集合,再给你一个没有重复元素X集合,X集合有如下操作 ①挑选某个元素*2 ②某 ...

  6. 线段树 或者 并查集 Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C

    http://codeforces.com/contest/722/problem/C 题目大意:给你一个串,每次删除串中的一个pos,问剩下的串中,连续的最大和是多少. 思路一:正方向考虑问题,那么 ...

  7. Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) D. Generating Sets 贪心

    D. Generating Sets 题目连接: http://codeforces.com/contest/722/problem/D Description You are given a set ...

  8. Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C. Destroying Array 带权并查集

    C. Destroying Array 题目连接: http://codeforces.com/contest/722/problem/C Description You are given an a ...

  9. Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) A. Broken Clock 水题

    A. Broken Clock 题目连接: http://codeforces.com/contest/722/problem/A Description You are given a broken ...

  10. Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C. Destroying Array

    C. Destroying Array time limit per test 1 second memory limit per test 256 megabytes input standard ...

随机推荐

  1. js案例分析

    名字取的高大上,其实只是我平时上网浏览遇到的一些我感觉还不错的小题目,再加上我或者是我在网上找到的一些理解,就保存到这里了. 2019/4/2  最新开了个新坑,是一个javascipt30的一些案例 ...

  2. jquery动态生成二维码添加自定义logo

    动态生成二维码中间带logo. jquery.qrcode.js 动态生成二维码api很简单. 引入jquer(版本任意),引入jquery.qrcode.js 不需要中间带logo这样就可以了.带l ...

  3. c/c++排坑(3) -- c/c++中的switch语句

    switch语句的简单介绍 一个 switch 语句允许测试一个变量等于多个值时的情况.每个值称为一个 case,且被测试的变量会对每个 switch case 进行检查. switch(expres ...

  4. vue数据绑定源码

    思路分析 数据的双向绑定,就是数据变化了自动更新视图,视图变化了自动更新数据,实际上视图变化更新数据只要通过事件监听就可以实现了,并不是数据双向绑定的关键点.关键还是数据变化了驱动视图自动更新. 所有 ...

  5. Excel表格

    自己一个一个试出来,并写上解释. 还不熟练,待多写代码多练习. #!/usr/bin/python # -*- coding:utf-8 -*- import os import xlwt impor ...

  6. 洋葱浏览器(Tor Browser)

    第一,洋葱路由器简介 Tor Browser 是個內建「翻牆」功能的網路瀏覽器,藉由「洋蔥路由, The Onion Router (Tor)」匿名瀏覽技術,將上網時所傳遞的訊息層層加密保護,讓使用者 ...

  7. 第八节:numpy之四则运算与逻辑运算

  8. NLTK学习笔记(七):文本信息提取

    目录 实体识别:分块技术 分块语法的构建 树状图 IOB标记 开发和评估分块器 命名实体识别和信息提取 如何构建一个系统,用于从非结构化的文本中提取结构化的信息和数据?哪些方法使用这类行为?哪些语料库 ...

  9. Maven pom 配置简介

    1. groupId artifactId version 2. dependencies 3. plugins http://shmilyaw-hotmail-com.iteye.com/blog/ ...

  10. Maven学习总结(8)——使用Maven构建多模块项目

    Maven学习总结(八)--使用Maven构建多模块项目 在平时的Javaweb项目开发中为了便于后期的维护,我们一般会进行分层开发,最常见的就是分为domain(域模型层).dao(数据库访问层). ...