蓝桥杯抱佛脚第四天|前缀和,差分对应练习

题单:【蓝桥杯】蓝桥杯省一秘诀(国赛题单看简介) - 题单 - 洛谷 | 计算机科学教育新生态

状态:差分没看太懂,前缀和倒是有熟练了一点

P8649 蓝桥杯 2017 省 B k 倍区间

题目链接:P8649 [蓝桥杯 2017 省 B k 倍区间 - 洛谷](https://www.luogu.com.cn/problem/P8649 "蓝桥杯 2017 省 B] k 倍区间 - 洛谷")

题目描述

给定一个长度为 N 的数列,A 1,A 2,⋯A**N ,如果其中一段连续的子序列 A**i ,A**i +1,⋯A**j (ij ) 之和是 K 的倍数,我们就称这个区间 *i* ,*j* K 倍区间。

你能求出数列中总共有多少个 K 倍区间吗?

输入格式

第一行包含两个整数 NK (1≤N ,K≤105)。

以下 N 行每行包含一个整数 A**i (1≤A**i≤105)。

输出格式

输出一个整数,代表 K 倍区间的数目。

输入输出样例

输入 #1

复制代码
5 2
1  
2  
3  
4  
5  

输出 #1

复制代码
6

说明/提示

时限 2 秒, 256M。蓝桥杯 2017 年第八届

这道题要是模拟的话会超时,依旧使用前缀和的思想来解决。子区间 i, j 的和等于 prej - prei-1(其中 pre0=0,pret 表示前 t 个元素的和)。该和是 K 的倍数当且仅当 (prej - prei-1) % K == 0,即 prej % K == prei-1 % K。所以前缀和里存的是前缀和取模后的余数,

复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
    int N, K;
    cin >> N >> K;    
    vector<long long> cnt(K, 0);  // 统计每个余数出现的次数
    cnt[0] = 1;                   // 初始前缀和为0,余数为0  
    long long ans = 0;            //存放最后的结果
    long long sum = 0;            // 当前前缀和   
    for (int i = 0; i < N; ++i) {
        int x;
        cin >> x;
        sum = (sum + x) % K;      // 更新当前前缀和模K
        ans += cnt[sum];          // 加上之前相同余数的个数
        cnt[sum]++;               // 当前余数出现次数加1
    }    
    cout << ans << endl;
    return 0;
}

CF816B Karen and Coffee

题目链接:CF816B Karen and Coffee - 洛谷

题目描述

为了在上课时保持清醒和专注,Karen 需要喝点咖啡!

Karen 是一位咖啡爱好者,她想知道冲泡完美咖啡的最佳温度。实际上,她花了一些时间阅读了几本食谱,包括备受赞誉的《The Art of the Covfefe》。

她一共掌握了 n 种咖啡配方。第 i 个配方建议咖啡应在 l**ir**i 度(包含端点)之间冲泡,以获得最佳口感。

Karen 认为,如果有至少 k 个配方推荐某个温度,则该温度为可接受温度。

Karen 的想法总是变化多端,于是她总共提出了 q 个问题。每个问题,她都会给定一个温度范围 ab,想让你告诉她,在这个范围内有多少个可接受的整数温度。

输入格式

输入的第一行包含三个整数 n , k (1≤kn ≤200000)、q (1≤q≤200000),分别表示配方数量、某个温度被判定为可接受所需的最少配方数,以及 Karen 提出的查询个数。

接下来的 n 行描述每个配方。具体地,第 i 行包含两个整数 l**ir**i (1≤l**ir**i ≤200000),表示第 i 个配方推荐咖啡应在 l**ir**i 度(包含端点)之间冲泡。

接下来的 q 行描述各个问题。每行包含两个整数 ab (1≤ab ≤200000),表示她想知道在 ab(包含端点)度之间有多少个可接受的整数温度。

输出格式

对于每一个问题,输出一行一个整数,表示在 ab 度之间有多少个可接受的整数温度。

输入输出样例

输入 #1

复制代码
3 2 4
91 94
92 97
97 99
92 94
93 97
95 96
90 100

输出 #1

复制代码
3
3
0
4

输入 #2

复制代码
2 1 1
1 1
200000 200000
90 100

输出 #2

复制代码
0

说明/提示

在第一个测试点中,Karen 掌握了 3 个配方。

  1. 第一个推荐温度区间为 91 到 94 度(包含端点)。

  2. 第二个推荐温度区间为 92 到 97 度(包含端点)。

  3. 第三个推荐温度区间为 97 到 99 度(包含端点)。

只要某个温度区间内至少有 2 个配方推荐,则该温度为可接受温度。

她一共提出了 4 个问题。

在第一个询问中,她想知道在 92 到 94 度之间的可接受整数温度有多少。答案是 3,因为 92, 93, 94 度都是可接受的。

在第二个询问中,她想知道在 93 到 97 度之间的可接受整数温度有多少。答案是 3,因为 93, 94, 97 度都是可接受的。

在第三个询问中,她想知道在 95 到 96 度之间的可接受整数温度有多少。没有可接受的温度。

在最后一个询问中,她想知道在 90 到 100 度之间有多少个可接受的整数温度。答案是 4,分别是 92, 93,94,97 度。

在第二个测试点中,Karen 掌握了 2 个配方。

  1. 第一个配方建议只在 1 度冲泡咖啡。

  2. 第二个配方建议只在 200000 度冲泡咖啡。

只要某个温度区间内至少有 1 个配方推荐,则该温度为可接受温度。

她有且仅有一个问题,询问在合理范围内有多少可接受整数温度。实际上没有。

这是一个典型的差分数组 +和前缀和的应用,用于解决区间覆盖计数和区间查询的问题。假设我们有一个数组 cover,长度等于温度范围,初始全为 0。差分数组统计每个温度的覆盖次数。差分数组 diff 是这样定义的:diffi 表示 coveri 与 coveri-1 的差值(即 coveri - coveri-1)。反过来,如果我们知道 diff,就可以通过前缀和还原出 cover:

现在,如果我们想在区间 [l, r] 上每个位置都加 1,这在差分数组上如何体现?

  • l 位置加 1,会让从 l 开始的 cover 都增加 1。

  • 为了不让 r+1 及以后的位置也增加,我们还要在 r+1 位置减 1。

    diffl += 1 diffr+1 -= 1

    这样,最后对 diff 求一遍前缀和,就能得到每个温度的实际覆盖次数 cover。

复制代码
#include<stdio.h>
using namespace std;
int f[200005];
int main(){
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    int i;
    int max=0;
    for(i=1;i<=n;i++){//差分代码
        int a,b;
        scanf("%d%d",&a,&b);
        f[a]+=1;f[b+1]-=1;
        if(b>max)max=b;
    }
    for(i=1;i<=max;i++){
        f[i]=f[i-1]+f[i];
    }
    for(i=1;i<=200000;i++){//前缀和
        if(f[i]>=m)f[i]=1+f[i-1];
        else f[i]=f[i-1];
    }
    for(i=1;i<=k;i++){
        int l,r;
        scanf("%d%d",&l,&r);
        printf("%d\n",f[r]-f[l-1]);//前缀和计算
    }
    return 0;
} 
​
相关推荐
微露清风19 分钟前
模拟算法学习记录
学习·算法
问商十三载1 小时前
2026法律行业AI引擎生成式优化怎么优化?三层专业加固提排名,零成本提33%引用率附适配表
java·前端·人工智能·算法
zander2581 小时前
138. 随机链表的复制
数据结构·算法·链表
过期动态1 小时前
【LeetCode 热题 100】找到字符串中所有字母异位词
java·数据结构·算法·leetcode·职场和发展·rabbitmq
来一碗刘肉面1 小时前
栈在递归中的应用
数据结构·算法
8K超高清2 小时前
博冠获中国电影电视技术学会科技进步奖
人工智能·科技·算法·安全·接口隔离原则·智能硬件
微石科技2 小时前
长期慢病如何做好居家管理?宁波微石科技星梦云康改善周期数据零散短板
大数据·科技·物联网·算法
微露清风2 小时前
快速排序算法学习记录
学习·算法·排序算法
梓䈑8 小时前
【算法题攻略】BFS 解决FloodFill 算法、最短路问题、多源BFS 和 拓扑排序
c++·算法·宽度优先