CCF CSP 202112-2 序列查询新解
单纯地讲思路有些难懂,这里结合一个实际例子来说明:
我们假设A = {0,1,3},n = 2,N = 10,r = 10 / (2 + 1) = 3。
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
f(i) | 0 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
g(i) | 0 | 0 | 0 | 1 | 1 | 1 | 2 | 2 | 2 | 3 |
|g(i) - f(i)| | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 |
肯定不能蠢到遍历所有的i,求|g(i) - f(i)|的和,这样做铁定超时。在做上一题(202112-1,序列查询)的时候,应该要想到需要遍历的是所有的f(i),而不是i。
那么, 对于一个给定的f(i)而言,我们怎么求这个区间里|g(i) - f(i)|之和?
以上表中f(i) = 1时为例,区间内的g(i) = {0,0}。这一段区间是比较特殊的,因为区间内的所有g(i)都小于等于这个f(i)。这时问题就比较好办了,这个区间里|g(i) - f(i)|之和等于区间里f(i)之和减去区间里g(i)之和。
如何快速求区间里f(i)之和,不用我再解释。关键是如何快速求区间里g(i)之和。我们令g(i)的前缀和为h(i),给定的f(i)区间里i的范围是[lft,rgt],那么求区间里g(i)之和其实就是求h(rgt) - h(lft - 1)。例如,求f(i) = 1时g(i)之和,就是求h(2) - h(1 - 1)。
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
g(i) | 0 | 0 | 0 | 1 | 1 | 1 | 2 | 2 | 2 | 3 |
h(i) | 0 | 0 | 0 | 1 | 2 | 3 | 5 | 7 | 9 | 12 |
如何计算g(i)的前缀和h(i),有简便的方法。g(i)的前k(这里k从0开始)项,是由r个首项为0、项数为(k + 1) / r、公差为1的等差数列,以及(k + 1) % r个k / r构成的。举例来说,g(i)的前7项{0, 0, 0, 1, 1, 1, 2,2}是由3个首项为0、项数为2、公差为1的等差数列{0, 1},以及2个2构成的。那么我们可以知道h(i) = r * ((i + 1) / r - 1) * ((i + 1) / r) / 2 + (i + 1) % r * (i / r)。
现在,我们已经知道了给定一个f(i),如果对应区间里g(i)全部小于等于该f(i)时,怎么求这个区间里|g(i) - f(i)|之和。如果对应区间里g(i)全部大于等于该f(i)呢?那么只是改成用区间里g(i)之和减去区间里f(i)之和罢了。但是还有一种特殊情况,那就是区间里的g(i)既有小于f(i)的,也有大于f(i)的。这个时候我们直接把区间从g(i) = f(i)处一分为二,左半边的g(i)全部小于f(i),右半边的g(i)全部大于f(i),分别计算区间里|g(i) - f(i)|之和——以f(i) = 2时为例,把f(i) = 2的区间从i = 6处分为两半,那么左半边的g(i) = {1,1,1,2},右半边的g(i) = {2,2,3},分别计算这两半就可以了。
#include <bits/stdc++.h>
using namespace std;long long h(long long i, long long r) { //求g(i)的前缀和h(i)if (i < 0) return 0;else return r * ((i + 1) / r - 1) * ((i + 1) / r) / 2 + (i + 1) % r * (i / r);
}long long cal(long long fi, long long lft, long long rgt, long long r) { //给定一个f(i),计算区间里的|g(i)-f(i)|之和,前提是g(i)全部小于等于或者全部大于等于f(i)return abs(h(rgt, r) - h(lft - 1, r) - fi * (rgt - lft + 1));
}int main()
{long long n, N, t;cin >> n >> N;vector<long long> a = {0};for (int i = 0; i < n; ++i) {cin >> t;a.push_back(t);}a.push_back(N);long long r = N / (n + 1), ans = 0;for (long long fi = 0; fi <= n; ++fi) { //遍历每个f(i)long long lft = a[fi], rgt = a[fi + 1] - 1;if (lft / r >= fi || rgt / r <= fi) ans += cal(fi, lft, rgt, r); //如果区间内g(i)全部小于等于或者全部大于等于f(i),直接使用cal函数else ans += cal(fi, lft, r * fi, r) + cal(fi, r * fi + 1, rgt, r); //否则将区间分成两半,分别使用cal函数}cout << ans << endl;return 0;
}
CCF CSP 202112-2 序列查询新解相关推荐
- CCF CSP 序列查询新解
CCF CSP 序列查询新解(C语言) 题目背景 上一题"序列查询"中说道: A=[A0,A1,A2,⋯,An] 是一个由 n+1 个 [0,N) 范围内整数组成的序列,满足 0= ...
- CSP CCF: 202112-2 序列查询新解 (C++)
题目链接:计算机软件能力认证考试系统 试题编号: 202112-2 试题名称: 序列查询新解 时间限制: 1.0s 内存限制: 512.0MB 题目背景 上一题"序列查询"中说道: ...
- CCF 202112-2 序列查询新解 python 满分
CCF 202112-2 序列查询新解 python 满分 题目叙述 问题描述:略 输入格式:略 输出格式:略 样例 满分证明 解题思路 01Python超时70分 02满分python思路 第一,计 ...
- CCF CSP202112-2 序列查询新解
CCF CSP202112-2 序列查询新解 题目背景 上一题"序列查询"中说道: A=[A0,A1,A2,⋯,An]A=[A_0,A_1,A_2,⋯,A_n]A=[A0,A1 ...
- ~5 ccf 2021-12-2 序列查询新解
序列查询新解 题目描述 输入 输出 样例输入 样例输出 子任务 源代码 关于这题 题目描述 输入 输出 样例输入 样例1 3 10 2 5 8 样例2 9 10 1 2 3 4 5 6 7 8 9 样 ...
- CCF-CSP-202112-2:序列查询新解(C++11题解)
文章目录 问题描述 解题思路 AC代码 问题描述 题目来源:CCF-CSP-202112-2:序列查询新解 解题思路 思路稍后再补. AC代码 PA了一次,是因为没开long long #includ ...
- CCF-CSP 202112-2 序列查询新解
题目:序列查询新解 思路:在f区间内划分g区间,注意g区间左端点的定值,不断移动g区间(长度都为r),当g区间末端点超出f的范围,进入下一个f循环 #include<bits/stdc++.h& ...
- CSP 序列查询新解 202112-2
用前缀和的思想,但是直接这样还是会超时. for(int i=0;i < N;i++) g[i] = g[i-1] + i/r; #include <iostream> #inclu ...
- CCF - 202112-2 - 序列查询新解
给出一个A数组,A = [0,2,5,8],n = 3,N = 10,r = 2: 在样例中可以看出在[0,2),[2,5),[5,8),[8,10)这些区间内,我们处在其中任何一个区间中时,f(i) ...
最新文章
- 2022-2028年中国高强度钢行业投资分析及前景预测报告
- 把委托说透(2):深入理解委托
- php提示行号,在php中使用trigger_错误时如何获得正确的行号?
- 我理解的javascript事件循环(一)
- anacondapythonyolo3配置_Windows anaconda 运行yolov3
- 【每日一题】5月7日题目精讲 「火」皇家烈焰
- threejs向量夹角和夹角方向
- MySQL 之 存储过程
- shell脚本发邮件内容html,Shell发送邮件以HTML展示
- 深入解析 ext2 文件系统
- 小程序开发教程 微信小程序视频教程
- 35 个非主流数据库
- 按夏普计算机技巧,股票投资策略:怎样用夏普比率Sharpe Ratio寻找强势股
- shfileoperation C#无法读源文件或磁盘XP系统1026错误
- 验证手机号或座机号的合法性
- hbase snappy 安装_Hadoop HBase 配置 安装 Snappy 终极教程
- 由于找不到C:\InetPub\ftproot\Tipray\Ldterm\ghijt32.DLL,无法继续执行代码。重新安装程序可能会解决此问题。
- java利用数组求平均值_Java程序使用数组计算平均值
- DPDK and XDP and ebpf
- 异常处理 --- 一些垂死挣扎的代码
热门文章
- 华为云数据库-GaussDB for MySQL数据库
- android切环境插件,Android Studio 2.0 - 插件太旧,请更新到更新版本,或设置ANDROID_DAILY_OVERRIDE环境变量...
- 贪吃蛇小游戏——C语言
- 哈佛管理大师学习笔记
- angular4 ng build --prod 报错:Module not found: Error: Can't resolve './$$_gendir/app/app.module.ngfac
- Android传感器---Environment Sensor
- 搭建Vue版Ant Design Pro后台管理系统
- B 字符串处理1000MS64MB Description 输入一个英文名字。去掉该英文名字两端的空格,并首字母大写后,输出问候语Hello, 加名字 Input 一个英文名字 Output 去
- slice和splice
- Struts2-062_RCE简单复现(CVE-2021-31805)