bzoj5016 & loj2254 [Snoi2017]一个简单的询问 莫队
题目传送门
https://lydsy.com/JudgeOnline/problem.php?id=5016
题解
原式是这样的
\]
因为一次询问需要用到两个区间,本来按理说最擅长两个区间的查询的主席树,这里也没有办法建立。
然后分块或者莫队的话也无能为力。
于是我们考虑对询问本身做一些修改,使得一次询问只涉及两个参数。
\]
这样,我们令 \(g(a, b)\) 表示 \(\sum\limits_{x = 0}^{\infty} get(1, a, x) \cdot get(1, b, x)\),那么我们就把上面的一个询问分解成了 \(4\) 个询问。
然后 \(g(a, b)\) 可以对 \(a, b\) 进行莫队完成。
时间复杂度 \(O(n\sqrt{4m})\)。这样写复杂度似乎不是很标准,因为复杂度里面不应该有任何常数。
#include<bits/stdc++.h>
#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back
template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}
typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
}
const int N = 50000 + 7;
#define bl(x) (((x) - 1) / blo + 1)
int n, m, blo, Q;
ll val;
int a[N], cl[N], cr[N];
ll ans[N];
struct Query {
int opt, l, r;
ll *ans;
inline Query() {}
inline Query(const int &opt, const int &l, const int &r, ll *ans) : opt(opt), l(l), r(r), ans(ans) {
if (l > r) std::swap(this->l, this->r);
}
inline bool operator < (const Query &b) const { return bl(l) != bl(b.l) ? l < b.l : r < b.r; }
} q[N << 2];
inline void addl(int x) {
val += cr[a[x]];
++cl[a[x]];
}
inline void addr(int x) {
val += cl[a[x]];
++cr[a[x]];
}
inline void dell(int x) {
val -= cr[a[x]];
--cl[a[x]];
}
inline void delr(int x) {
val -= cl[a[x]];
--cr[a[x]];
}
inline void work() {
blo = sqrt(Q);
std::sort(q + 1, q + Q + 1);
int l = 0, r = 0;
for (int i = 1; i <= Q; ++i) {
while (r < q[i].r) addr(++r);
while (l < q[i].l) addl(++l);
while (l > q[i].l) dell(l--);
while (r > q[i].r) delr(r--);
*q[i].ans += q[i].opt * val;
}
for (int i = 1; i <= m; ++i) printf("%lld\n", ans[i]);
}
inline void init() {
read(n);
for (int i = 1; i <= n; ++i) read(a[i]);
read(m);
for (int i = 1; i <= m; ++i) {
int l1, r1, l2, r2;
read(l1), read(r1), read(l2), read(r2);
q[++Q] = Query(1, r1, r2, ans + i);
if (l2 > 1) q[++Q] = Query(-1, l2 - 1, r1, ans + i);
if (l1 > 1) q[++Q] = Query(-1, l1 - 1, r2, ans + i);
if (l1 > 1 && l2 > 1) q[++Q] = Query(1, l1 - 1, l2 - 1, ans + i);
}
}
int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}
bzoj5016 & loj2254 [Snoi2017]一个简单的询问 莫队的更多相关文章
- 【BZOJ5016】[Snoi2017]一个简单的询问 莫队
[BZOJ5016][Snoi2017]一个简单的询问 Description 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计 ...
- 【bzoj5016】[Snoi2017]一个简单的询问 莫队算法
题目描述 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次. 输入 第一行,一个数字N,表 ...
- Gym101138D Strange Queries/BZOJ5016 SNOI2017 一个简单的询问 莫队、前缀和、容斥
传送门--Gym 传送门--BZOJ THUWC2019D1T1撞题可还行 以前有些人做过还问过我,但是我没有珍惜,直到进入考场才追悔莫及-- 设\(que_{i,j}\)表示询问\((1,i,1,j ...
- BZOJ5016:[SNOI2017]一个简单的询问(莫队)
Description 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次. Input 第 ...
- [SNOI2017]一个简单的询问
[SNOI2017]一个简单的询问 题目大意: 给定一个长度为\(n(n\le50000)\)的序列\(A(1\le A_i\le n)\),定义\(\operatorname{get}(l,r,x) ...
- BZOJ5016 Snoi2017一个简单的询问(莫队)
容易想到区间转化成前缀和.这样每个询问有了二维坐标,莫队即可. #include<iostream> #include<cstdio> #include<cmath> ...
- [bzoj5016][Snoi2017]一个简单的询问
来自FallDream的博客,未经允许,请勿转载,谢谢. 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计算区间[l,r]中 ...
- [SNOI2017]一个简单的询问【莫队+容斥原理】
题目大意 给你一个数列,让你求两个区间内各个数出现次数的乘积的和. 分析 数据范围告诉我们可以用莫队过. 我并不知道什么曼哈顿什么乱七八糟的东西,但是我们可以用容斥原理将这个式子展开来. \[\sum ...
- 【LOJ2254】SNOI2017一个简单的询问
莫队,每次询问的是两个区间,就把区间拆开,分开来算就好了. 借鉴了rank1大佬的玄学排询问的姿势. #include<bits/stdc++.h> #define N 50010 typ ...
随机推荐
- Python学习笔记(三)- SyntaxError: Non-ASCII character '\xe7' in file
在编辑Python时,当有中文输出或者注释时,出现错误提示:“SyntaxError: Non-ASCII character '\xe7' in file“ 原因:python的默认编码文件是用的A ...
- Spring_Boot 简单例子
第一步创建项目: 创建项目地址:https://start.spring.io/ 接下来就下载到本地了 跟着加压 接着用idea打开:等待资源下载完成 我写了个简单的:增删改查 项目结构: dao层: ...
- mysql5.7多实例安装
[root@vhost1]# cd /opt/source[root@vhost1]#ls mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz[root@vhost1 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_07 缓冲流_4_缓冲流的效率测试_复制文件
把之前文件复制的代码复制到这里 一个字节一个字节的读取,复制文件 byte数组的形式 缓冲流测试 数组缓冲
- 40 insert语句的锁
40 insert语句的锁 上一篇文章中对mysql自增主键锁做了优化,尽量在申请到自增id后,就释放自增锁. 因此,insert语句是一个很轻量的操作,不过,这个结论对于”普通的insert”才生效 ...
- 腾讯重磅开源分布式NoSQL存储系统DCache
当你在电商平台秒杀商品或者在社交网络刷热门话题的时候,可以很明显感受到当前网络数据流量的恐怖,几十万商品刚开抢,一秒都不到就售罄:哪个大明星出轨的消息一出现,瞬间阅读与转发次数可以达到上亿.作为终端用 ...
- Appium-入门实例1
参考:(https://blog.csdn.net/zh175578809/article/details/76862590) 第一步:启动虚拟设备 在运行App之前,首先需要创建一个Android模 ...
- python函数及调用
python的函数是一段重复多次可调用的代码,依据python的函数,我们可以利用函数式的编程,来减少代码的重复. 在本章节中,详细的介绍python的函数,以及python的函数式编程的与众不同,函 ...
- Common Linux Commands 日常工作常用Linux命令
How to know CPU info cat /proc/cpuinfo arch How to know memory info: cat /proc/meminfo ...
- C#后台保存Cookie
一般是: Response.Cookies["backurl"].Expires.AddDays(2); 但是,IE浏览器保存Cookie用 Response.Cookies[&q ...