首页 > 其他分享 >AcWing 802.区间和

AcWing 802.区间和

时间:2022-09-03 11:24:36浏览次数:65  
标签:10 int back 离散 push alls 区间 802 AcWing

题目链接:https://www.acwing.com/problem/content/804/

好像理解了,但又没完全理解....写个题解再好好理解一下。

百度说:离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。

简单来说就是通过映射关系,将大范围里面很少的数据进行小范围存储,压缩了使用空间

 

离散化常用的一般步骤:

1、对数据进行排序

2、对数据进行去重

3、离散化数据处理

我将本题分为这几步:

1、读入所有操作数据

2、离散化数据。将 n 次操作的坐标,m 次查询的 [l, r] 进行离散化

3、求离散化后数据前缀和

4、将 m 次查询的区间和输出。注意 l 和 r 都需要对应到离散化数据

 

find 函数的功能:输入映射前的位置 x ,返回映射后的位置+1。(+1的目的是为了求区间和时少一步下表为0的判断)

alls[N] 为什么要开 3e5+10?因为最多可以执行 n 次插入操作,m 次询问操作,而每次询问操作中会包含两个坐标。所以说虽然题目中说数轴是无限长,但离散化的数组只需要开 3e5+10 就够了。

关于为什么要去重,引用一个大佬的题解中的图:

 

然后分析一下样例:

 


 

放AC代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 3e5+10;//n次查询和m次询问相关数据量的上届
 4 int n, m;
 5 int a[N];//存储坐标插入的值
 6 int s[N];//存储a的前缀和
 7 vector<int> alls;//存储(所有与操作有关的)下标
 8 vector<pair<int,int> > add, query;//存储插入和询问操作的数据
 9 
10 int find(int x)
11 {//返回的是输入的坐标的离散化下标+1
12     int l = 0, r = alls.size() - 1;
13     while (l < r)
14     {
15         int mid = l + r >> 1;
16         if (alls[mid] >= x) r=mid;
17         else l = mid + 1;
18     }
19     return r + 1;
20 }
21 
22 int main()
23 {
24     cin >> n >> m;
25     for(int i=1; i<=n; i++)
26     {
27         int x, c;
28         cin >> x >> c;
29         add.push_back({x, c});
30         alls.push_back(x);//把x加到待离散化的数组中
31     }
32     for(int i=1; i<=m; i++)
33     {
34         int l, r;
35         cin >> l >> r;
36         query.push_back({l, r});
37         alls.push_back(l);//把l加到待离散化的数组中
38         alls.push_back(r);//同
39     }
40 
41     //排序+去重
42     sort(alls.begin(),alls.end());
43     alls.erase(unique(alls.begin(),alls.end()),alls.end());
44 
45     //执行前n次的插入操作
46     for(auto item : add)
47     {
48         int x = find(item.first);
49         a[x] += item.second;//在离散化之后的位置上加上要加的数
50     }
51 
52     //预处理前缀和
53     for(int i=1; i<=alls.size(); i++)
54         s[i] = s[i-1] + a[i];
55 
56     //处理后m次询问操作
57     for(auto item:query)
58     {
59         int l = find(item.first);//映射后的位置
60         int r = find(item.second);
61         cout << s[r]-s[l-1] << endl;
62     }
63     return 0;
64 }

 

标签:10,int,back,离散,push,alls,区间,802,AcWing
From: https://www.cnblogs.com/marswithme/p/16652193.html

相关文章

  • acwing语法基础课第一讲
    这堂课主要讲的是输入输出,以及顺序语句。以上,是我的笔记,包括课堂笔记以及后来做题总结的知识点。我需要强调的是!啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊......
  • AcWing算法基础课---第三讲基础算法---01DFS和BFS
    DFSAcWing842.排列数字#include<iostream>usingnamespacestd;constintN=10;intn;intpath[N],st[N];voiddfs(intu){if(u==n){......
  • 区间 kth
    众所周知,区间kth有很多种求法。本文中的时间复杂度和分数均以实现P3834为准。为了更好地贴合现实,本文代码将更加符合学此算法时的实际情况。一、排序通过选择/冒......
  • ac802 区间和
    注意>>的运算顺序在加减之后#include<bits/stdc++.h>usingnamespacestd;constintN=300010;//intn,m;inta[N];//坐标插入的值in......
  • 涉及区间的查询
    1.找出一系列连续的值问题:判断哪些行表示一系列连续的项目。即某一行项目开始时间和前一行的项目结束时间是一致的。示例表:  解决方案:利用窗函数......
  • AcWing秋招每日一题——week4
    Mon题目有效的快速序列数目给你 n 笔订单,每笔订单都需要快递服务。请你统计所有有效的收件/配送序列的数目,确保第i个物品的配送服务 delivery(i)总是在其收件......
  • AcWing秋招每日一题——week3
    1、跳跃游戏题目给你一个整数数组 arr ,你一开始在数组的第一个元素处(下标为0)。每一步,你可以从下标 i 跳到下标 i+1、i-1或者j:i+1需满足:i+1<arr.l......
  • AcWing杯 - 第66场周赛
    比赛链接:[第66场周赛](竞赛-AcWing)先放代码,题解慢慢补AAcWing4606.奇偶判断#include<set>#include<map>#include<queue>#include<stack>#include<cmath>#i......
  • Acwing 第 66 场周赛 A-C
    2A,来晚+中间有事,第三题没写,但是写第三题的时候也感觉犯迷糊,读懂题意就好了AAcWing4606.奇偶判断题意:判断末位是偶数还是奇数跳过 BAcWing4607.字母补全题意......
  • 15.区间覆盖问题(贪心)
    题目描述:设x1,x2,……,xn是实直线上的n个点。用固定长度的闭区间覆盖这n个点,至少需要多少个这样的固定长度闭区间?对于给定的实直线上的n个点和闭区间的长度k,设......