单纯地讲思路有些难懂,这里结合一个实际例子来说明:
我们假设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 序列查询新解相关推荐

  1. CCF CSP 序列查询新解

    CCF CSP 序列查询新解(C语言) 题目背景 上一题"序列查询"中说道: A=[A0,A1,A2,⋯,An] 是一个由 n+1 个 [0,N) 范围内整数组成的序列,满足 0= ...

  2. CSP CCF: 202112-2 序列查询新解 (C++)

    题目链接:计算机软件能力认证考试系统 试题编号: 202112-2 试题名称: 序列查询新解 时间限制: 1.0s 内存限制: 512.0MB 题目背景 上一题"序列查询"中说道: ...

  3. CCF 202112-2 序列查询新解 python 满分

    CCF 202112-2 序列查询新解 python 满分 题目叙述 问题描述:略 输入格式:略 输出格式:略 样例 满分证明 解题思路 01Python超时70分 02满分python思路 第一,计 ...

  4. CCF CSP202112-2 序列查询新解

    CCF CSP202112-2 序列查询新解 题目背景 上一题"序列查询"中说道: A=[A0,A1,A2,⋯,An]A=[A_0,A_1,A_2,⋯,A_n]A=[A0​,A1​ ...

  5. ~5 ccf 2021-12-2 序列查询新解

    序列查询新解 题目描述 输入 输出 样例输入 样例输出 子任务 源代码 关于这题 题目描述 输入 输出 样例输入 样例1 3 10 2 5 8 样例2 9 10 1 2 3 4 5 6 7 8 9 样 ...

  6. CCF-CSP-202112-2:序列查询新解(C++11题解)

    文章目录 问题描述 解题思路 AC代码 问题描述 题目来源:CCF-CSP-202112-2:序列查询新解 解题思路 思路稍后再补. AC代码 PA了一次,是因为没开long long #includ ...

  7. CCF-CSP 202112-2 序列查询新解

    题目:序列查询新解 思路:在f区间内划分g区间,注意g区间左端点的定值,不断移动g区间(长度都为r),当g区间末端点超出f的范围,进入下一个f循环 #include<bits/stdc++.h& ...

  8. CSP 序列查询新解 202112-2

    用前缀和的思想,但是直接这样还是会超时. for(int i=0;i < N;i++) g[i] = g[i-1] + i/r; #include <iostream> #inclu ...

  9. 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) ...

最新文章

  1. 2022-2028年中国高强度钢行业投资分析及前景预测报告
  2. 把委托说透(2):深入理解委托
  3. php提示行号,在php中使用trigger_错误时如何获得正确的行号?
  4. 我理解的javascript事件循环(一)
  5. anacondapythonyolo3配置_Windows anaconda 运行yolov3
  6. 【每日一题】5月7日题目精讲 「火」皇家烈焰
  7. threejs向量夹角和夹角方向
  8. MySQL 之 存储过程
  9. shell脚本发邮件内容html,Shell发送邮件以HTML展示
  10. 深入解析 ext2 文件系统
  11. 小程序开发教程 微信小程序视频教程
  12. 35 个非主流数据库
  13. 按夏普计算机技巧,股票投资策略:怎样用夏普比率Sharpe Ratio寻找强势股
  14. shfileoperation C#无法读源文件或磁盘XP系统1026错误
  15. 验证手机号或座机号的合法性
  16. hbase snappy 安装_Hadoop HBase 配置 安装 Snappy 终极教程
  17. 由于找不到C:\InetPub\ftproot\Tipray\Ldterm\ghijt32.DLL,无法继续执行代码。重新安装程序可能会解决此问题。
  18. java利用数组求平均值_Java程序使用数组计算平均值
  19. DPDK and XDP and ebpf
  20. 异常处理 --- 一些垂死挣扎的代码

热门文章

  1. 华为云数据库-GaussDB for MySQL数据库
  2. android切环境插件,Android Studio 2.0 - 插件太旧,请更新到更新版本,或设置ANDROID_DAILY_OVERRIDE环境变量...
  3. 贪吃蛇小游戏——C语言
  4. 哈佛管理大师学习笔记
  5. angular4 ng build --prod 报错:Module not found: Error: Can't resolve './$$_gendir/app/app.module.ngfac
  6. Android传感器---Environment Sensor
  7. 搭建Vue版Ant Design Pro后台管理系统
  8. B 字符串处理1000MS64MB Description 输入一个英文名字。去掉该英文名字两端的空格,并首字母大写后,输出问候语Hello, 加名字 Input 一个英文名字 Output 去
  9. slice和splice
  10. Struts2-062_RCE简单复现(CVE-2021-31805)