题意:一个数列,给出这个数列中的某些位置的数,给出所有相邻的三个数字的和,数列头和尾处给出相邻两个数字的和。有若干次询问,每次问某一位置的数字的最大值。

分析:设数列为a1~an。首先通过相邻三个数字的和我们可以求出a3,a6,a9……是多少。a3=sum(a1,a2,a3)-sum(a1,a2)。a6=sum(a4,a5,a6)-sum(a3,a4,a5)。后面依次类推。

推到了数列的最右面,如果恰好知道了an或者a(n-1)中的一个,那么可以通过sum(an,a(n-1))减去它来求得另一个。

这个题还有个性质就是,只要知道数列中连续的两位就可以通过不断向两侧延伸的方法得到整个数列。因为任意相邻三个的和都知道,知道其中两个数自然可以得到第三个。

所以我们如果知道了最后两位则一定可以知道整个数列。同样如果根据已知的数列中的数和推出的数能得知两个已知的相邻的数的话,也可推出整个数列。

唯一一种无法确定该数列的情况就是我们,没有推出最后的两个数(即n%3==2的情况),且数列中已知给出的数也没有提供任何推出信息以外的信息。

这时我们就获得了一个不确定的数列,将数列中的数字ai按照i%3结果的不同分成三组,得0则已知。

得1的数之间互相是同增同减的,因为他们互相之间的差是一样的。a1-a4=sum(a1,a2,a3)-sum(a2,a3,a4)。得2的同理。所以这些同增同减的数字会同时取得最大值或最小值。

得1和得2的之间是此消彼涨的,因为他们互相之间的和是一样的。a1+a2=sum(a1,a2)    a2+a4=sum(a2,a3,a4)-a3    a4+a5=sum(a3,a4,a5)-a3 所以得1的取得最小值则得2的取得最大值,反之亦然。

在符合了这些和与差的条件之后,唯一会导致数列不合法的情况就是出现负数。我们只需要先对得1的随意娶个值,并推出整个数列后,根据最小数值调整所有得1的取值,使最小的那个数恰好为0。

这样就可以使得1的取最小值,即让得2的取得最大值。

同理可以求得得1的最大值。

存储好各种最大值之后按题目中的询问输出即可。计算最大值需要O(n),每次询问需要O(1),共m次询问,总复杂度为O(n + m)。

#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;#define MAX_NUM 100005int array[MAX_NUM], array1[MAX_NUM], array2[MAX_NUM];
int sum[MAX_NUM];
int num;
int query_num;
bool filled;void cal_left(int pos, int array[])
{for (int i = pos - 2; i > 0; i--)array[i] = sum[i + 1] - array[i + 1] - array[i + 2];
}void cal_right(int pos, int array[])
{for (int i = pos + 2; i <= num; i++)array[i] = sum[i - 1] - array[i - 1] - array[i - 2];
}void input()
{int pos = -1;for (int i = 1; i <= num; i++){scanf("%d", &array[i]);if (i % 3 != 0 && array[i] != -1)pos = i;}for (int i = 1; i <= num; i++)scanf("%d", &sum[i]);array[0] = 0;for (int i = 3; i <= num; i += 3)array[i] = sum[i - 1] - (sum[i - 2] - array[i - 3]);if (num % 3 == 2 && pos == -1)return;filled = true;if (array[num] != -1)array[num - 1] = sum[num] - array[num];if (array[num - 1] != -1)array[num] = sum[num] - array[num - 1];if (array[num] != -1)cal_left(num, array);array[num + 1] = 0;if (pos != -1){if (array[pos - 1] != -1)pos--;cal_left(pos + 1, array);cal_right(pos, array);}
}void work()
{scanf("%d", &query_num);for (int i = 0; i < query_num; i++){int a;scanf("%d", &a);a++;if (filled){printf("%d\n", array[a]);continue;}if (a % 3 == 1)printf("%d\n", array1[a]);else if (a % 3 == 2)printf("%d\n", array2[a]);elseprintf("%d\n", array[a]);}
}void make2()
{memcpy(array2, array, sizeof(array2));array2[1] = 0;array2[2] = sum[1] - array2[1];cal_right(1, array2);array2[1] -= *min_element(array2 + 1, array2 + num + 1);array2[2] = sum[1] - array2[1];cal_right(1, array2);
}void make1()
{memcpy(array1, array, sizeof(array1));array1[num] = 0;array1[num - 1] = sum[num] - array1[num];cal_left(num, array1);array1[num] -= *min_element(array1 + 1, array1 + num + 1);array1[num - 1] = sum[num] - array1[num];cal_left(num, array1);
}int main()
{while (scanf("%d", &num) != EOF){filled = false;input();if (!filled){make2();make1();}work();}return 0;
}

View Code

转载于:https://www.cnblogs.com/rainydays/p/3334641.html

2013 ACM/ICPC 长沙网络赛J题相关推荐

  1. HDU - 5877 Weak Pair 2016 ACM/ICPC 大连网络赛 J题 dfs+树状数组+离散化

    题目链接 You are given a rootedrooted tree of NN nodes, labeled from 1 to NN. To the iith node a non-neg ...

  2. HDU - 5875 2016 ACM/ICPC 大连网络赛 H题 暴力

    题目链接 题意:给你一个区间l,r一直将val[l]模上val[l+1],val[l+2]...val[r],因为一个模上比前一个数小数是没有意义的,所以需要将每一个点找到右边第一个小于他的点就行. ...

  3. HDU - 5876 Sparse Graph 2016 ACM/ICPC 大连网络赛 I题 bfs+set+补图最短路

    题目链接 题意:给的补图,让你求一个源点到其他点的最短距离,因为图太稠密了, 用dij以及spfa根本不得行,这里只能用一种我不会方法来进行,这里用了bfs的方法以及set来维护,分别set维护一个未 ...

  4. 乌鲁木齐网络赛J题(最小费用最大流模板)

    ACM ICPC 乌鲁木齐网络赛 J. Our Journey of Dalian Ends 2017-09-09 17:24 243人阅读 评论(0) 收藏 举报  分类: 网络流(33)  版权声 ...

  5. 2019 ACM - ICPC 上海网络赛 E. Counting Sequences II (指数型生成函数)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  6. 2019 ICPC 徐州网络赛 J.Random Access Iterator

    2019 ICPC 徐州网络赛 J.Random Access Iterator 题目大意:给你n个点和n-1条边(树形结构),保证1为根节点,通过以下方式dfs遍历: 询问dfs到最深节点的概率(有 ...

  7. luogu 1327 数列排序 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 J题 循环节

    luogu 1327 数列排序 题意 给定一个数列\(\{an\}\),这个数列满足\(ai≠aj(i≠j)\),现在要求你把这个数列从小到大排序,每次允许你交换其中任意一对数,请问最少需要几次交换? ...

  8. 2017乌鲁木齐网络赛 j 题

    题目连接 : https://nanti.jisuanke.com/t/A1256 Life is a journey, and the road we travel has twists and t ...

  9. 2013年长沙网络赛G题

    题目:http://acm.zju.edu.cn/changsha/showProblem.do?problemId=28 题意:给一个数n,范围是[2,80000],使用加,乘运算和最多3个素数,有 ...

最新文章

  1. 【PAT乙级】1028 人口普查 (20 分)
  2. intellij-IDE运行Java程序报错:java: -source 1.5 中不支持 lambda 表达式 有用
  3. think python 2ed_Think Python 2ed 笔记(二)
  4. Flex Graphics
  5. 51nod 1275 连续子段的差异(twopointer+单调队列)
  6. 40vf什么意思_LED 的基本术语VF、IV、WL、IR 解释及光通量换算关系
  7. Algo: Basic
  8. Jenkins在Windows下的安装与配置
  9. Linux的常见的发行版以及不同发行版之间的联系与区别
  10. AES加解密流程及方法
  11. Dingo Api请求接口404?
  12. Spring Boot入门(08):整合Mybatis访问MySQL实现增删改查 | 超级详细,建议收藏
  13. Jenkins 重启出现Error 403 No valid crumb was included in the request
  14. Retrying connect to server: xxx.xxx.xxx.xxx:8032. Already tried 0 time(s)
  15. 什么是ESB(企业服务总线)
  16. 联邦学习(Federated Learning)详解以及示例代码
  17. Kafka创建topic
  18. JDBC连接Sql_Server_2005
  19. 当你的开源软件被他人申请专利
  20. GOFLY在线客服系统/外贸网站在线客服+多语言支持 外贸网站即时通讯工具/中英文切换教程...

热门文章

  1. 高级软件工程第七次作业:东理三剑客团队作业-随笔5
  2. Jenkins搭建Nodejs自动化测试
  3. Newtonsoft.Json.dll 反序列化JSON字符串
  4. mysql5.5.30源码安装及主从搭建
  5. GNOME Shell Extensions开发介绍
  6. 关于表单回车自动提交的讨论
  7. .Net FrameWork中的網絡操作
  8. iview中时间选择器可设置选择范围方法(一个月 一周等)
  9. linux安装meb工具,linux-docker下安装禅道全部
  10. 每输入四个字符添加一个中划线