NC19427 换个角度思考
题目
题目描述
给定一个序列,有多次询问,每次查询区间里小于等于某个数的元素的个数
即对于询问 \((l,r,x)\) ,你需要输出 \(\sum_{i=l}^{r}[a_i \le x]\) 的值
其中 \([exp]\) 是一个函数,它返回 \(1\) 当且仅当 \(exp\) 成立,其中 \(exp\) 表示某个表达式
输入描述
第一行两个整数 \(n,m\)
第二行 \(n\) 个整数表示序列 \(a\) 的元素,序列下标从 \(1\) 开始标号,保证 \(1 ≤ a_i ≤ 10^5\)
之后有 \(m\) 行,每行三个整数 \((l,r,k)\) ,保证 \(1 ≤ l ≤ r ≤ n\) ,且 \(1 ≤ k ≤ 10^5\)
输出描述
对于每一个询问,输出一个整数表示答案后回车
示例1
输入
5 1
1 2 3 4 5
1 5 3
输出
3
备注
数据范围
\(1 ≤ n ≤ 10^5\)
\(1 ≤ m ≤ 10^5\)
题解
知识点:树状数组,离线。
我们可以类比逆序对问题,求一个数 \(a_i\) 贡献的逆序对个数的公式 \(\displaystyle \sum_{j \leq i} [a_j > a_i]\) ,其中我们规定了 \(i\) 的枚举方向是从左到右,如此保证了 \(j\leq i\) 的偏序排除了干扰信息,再用数据结构维护 \([a_j > a_i]\) 的计算。同样的,我们可以把这个经典的公式变个形, \(\displaystyle \sum_{a_j > a_i} [j \leq i]\) ,也是同样可行的,我们从大到小枚举 \(a\) 保证 \(a_j > a_i\) 的偏序,再用数据结构维护 \([j \leq i]\) 的计算即可。
可以看出二维偏序问题中,离线将输入按照某偏序条件排序再枚举,等价于用了时间轴维护这个偏序,如此我们就可以使用线性数据结构(树状数组、线段树等)维护另一维偏序。
回到原问题,对于一个询问 \((l,r,x)\) 我们要计算 \(\displaystyle \sum_{i=l}^{r}[a_i \le x]\) ,我们可以转化为 \(\displaystyle \sum_{a_i \leq x} [l \leq i \leq r]\) 。我们可以利用时间轴维护 \(a_i < x\) 这个偏序,即将询问按 \(x\) 从小到大排序并枚举,随后用树状数组维护数字出现的区间查询即可。
但是显然,时间轴维护 \(l \leq i \leq r\) 不是那么显然,因为这不是单纯的一个偏序关系,其具有下界,需要维护数据的时效性。一个朴素的做法是带修莫队 \(O(n^{\frac{5}{3}})\) ,能过但很慢(我也不会qwq。另一个做法就是主席树,能天然维护这种关系(我更不会qwq。
时间复杂度 \(O((n+m) \log n + m \log m)\)
空间复杂度 \(O(n+m)\)
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<class T>
class Fenwick {
int n;
vector<T> node;
public:
Fenwick(int _n = 0) { init(_n); }
void init(int _n) {
n = _n;
node.assign(n + 1, T());
}
void update(int x, T val) { for (int i = x;i <= n;i += i & -i) node[i] += val; }
T query(int x) {
T ans = T();
for (int i = x;i;i -= i & -i) ans += node[i];
return ans;
}
T query(int x, int y) {
T ans = T();
ans += query(y);
ans -= query(x - 1);
return ans;
}
};
struct T {
int sum = 0;
T &operator+=(const T &x) { return sum += x.sum, *this; }
T &operator-=(const T &x) { return sum -= x.sum, *this; }
};
pair<int, int> a[100007];
struct Query {
int l, r, x, id;
}q[100007];
int ans[100007];
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1;i <= n;i++) {
int x;
cin >> x;
a[i] = { x,i };
}
for (int i = 1;i <= m;i++) {
int l, r, x;
cin >> l >> r >> x;
q[i] = { l,r,x,i };
}
sort(a + 1, a + n + 1, [&](auto a, auto b) {return a.first < b.first;});
sort(q + 1, q + m + 1, [&](auto a, auto b) {return a.x < b.x;});
int pos = 1;
Fenwick<T> fw(n);
for (int i = 1;i <= m;i++) {
while (pos <= n && a[pos].first <= q[i].x) {
fw.update(a[pos].second, { 1 });
pos++;
}
ans[q[i].id] = fw.query(q[i].l, q[i].r).sum;
}
for (int i = 1;i <= m;i++) cout << ans[i] << '\n';
return 0;
}
NC19427 换个角度思考的更多相关文章
- 一个想法(续二):换个角度思考如何解决IT企业招聘难的问题!
前言: 上一篇文章:一个想法:成立草根技术联盟对开发人员进行技术定级解决企业员工招聘难问题! 当时写文的思维,是从一个公益组织的角度的思考. 因此,有不少关于从利出发的反方观点,的确是值的思考! 任何 ...
- react+laravel与服务端渲染的几点思考
一.前后端完全分离 1.用React.js做MVC中的V,剩下的交给Laravel 2.Laravel用来做API接口开发. 3.好处:实现了前后端开发的分离,从而加快前后端开发效率.另外若是多端的如 ...
- 【腾讯Bugly干货分享】微信终端跨平台组件 mars 系列(二) - 信令传输超时设计
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/9DJxipJaaBC8yC-buHgnTQ 作者简介: ...
- 微服务和SOA服务
微服务和SOA都被认为是基于服务的架构,这意味着这两种架构模式都非常强调将“服务”作为其架构中的首要组件,用于实现各种功能(包括业务层面和非业务层面).微服务和SOA是两种差异很大的架构模式,但是他们 ...
- linux 让程序在后台运行的几种可靠方法
我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败.如何让命令提交后不受本地关闭终端窗口/网络断开 ...
- Linux学习之让进程在后台可靠运行的方法详解
我们经常会碰到这样的问题,用 telnet/ ssh 登录了远程的 Linux 服务器http://www.maiziedu.com/course/592/,运行了一些耗时较长的任务, 结果却由于网络 ...
- 【单元测试】NUint使用详解及Visual Studio配置
阅读目录 什么是单元测试? 为什么使用单元测试? NUint使用详解: 示例 属性 断言 简单测试 VS配置: External Tools Visual Nunit 2010 NUnit Test ...
- php cli配置文件问题
引言 今天在教别人使用protobuf的时候,无意中发现了一个php cli模式下的诡异问题,费了老半天的找到解决方法了,这里拿出来分享下. 问题描述 我们这边最先引入了protobuf协议,使用的是 ...
- Codeforces Round #238 (Div. 2) D. Toy Sum(想法题)
传送门 Description Little Chris is very keen on his toy blocks. His teacher, however, wants Chris to s ...
- if else 的妙用 —— 顾客视角
if (storedCash % 100 != 0) { System.out.println("请输入100的倍数!!!"); } else if(storedCash % 10 ...
随机推荐
- el-admin登录详解
1.进入登陆界面后,就会自动获取验证码. 2.前端访问auth/code接口获取后端生成的验证码(包括uuid,img,结果值),然后放入redis,设置2分钟过期,并返回识别码.图片url给前端. ...
- 基于leaflet地图可视化(一)
最近,在学习地图可视化是基于公司的项目.但公司在项目上居然用图片来代替.无语~~~项目效果图(第一版)如下: 突发奇想,2016年自己就接触过地图可视化.但那是没有深入研究.只会用R语言来实现点基础. ...
- laravel whereHas sum & addSelect sum
$users = User::select('id', 'username', 'coins', 'cut') ->when(request()->has('agent_tip_sum') ...
- 通用图像分割任务- 使用 Mask2Former 和 OneFormer
本文介绍两个领先的图像分割神经网络模型: Mask2Former 和 OneFormer.相关模型已经在 Transformers 提供. Transformers 是一个开源库,提供了很多便捷的先进 ...
- RTC月度小报5月丨教育aPaaS灵动课堂升级、抢先体验VUE版 Agora Web SDK、声网Agora与HTC达成合作
本月亮点速览 产品与技术: 声网Agora 教育 aPaaS 灵动课堂升级 视频通话/语音通话/互动直播 Native SDK 升级上线 3.4.2 版本 视频通话/语音通话/互动直播 Web SDK ...
- Go 语言:如何利用好 TDD 学习指针并了解 Golang 中的 error 处理
我们在上一节中学习了结构体(structs),Go语言:利用 TDD 驱动开发测试 学习结构体.方法和接口 它可以组合与一个概念相关的一系列值. 你有时可能想用结构体来管理状态,通过将方法暴露给用户的 ...
- 发布新版博客备份功能:生成 sqlite 数据库文件,vscode 插件可查看
大家好,最近我们重新开发了园子的博客备份功能,今天发布第一个预览版,欢迎大家试用. 点击博客后台侧边栏的博客备份进入新版博客备份: 点击创建备份按钮创建博客备份任务(目前每天只能创建一次备份),待备份 ...
- 安全测试之探索 windows 游戏扫雷
作者:京东工业 宛煜昕 扫雷游戏相信很多人都从小玩过,在那个电脑游戏并不多的时代,扫雷成为玩的热度蛮高的一款游戏之一,然而就在有一次,接触到了一次不寻常的扫雷过程,使得后来我也有了这个冲动,也来做一次 ...
- GLM:通用语言模型
ChatGPT已经火了一段时间了,国内也出现了一些平替,其中比较容易使用的是ChatGLM-6B:https://github.com/THUDM/ChatGLM-6B ,主要是能够让我们基于单卡自己 ...
- 记录关于Chromium系浏览器密码安全问题的一些思考
首先就是在此之前就看到有相关报道讲到Chrome等浏览器密码都在本地明文存储,而且权限要求很低,任何程序都可以随意读取,这方面的安全问题暂且不表. 今天使用Edge时候发现浏览器储存的密码,在我已经设 ...