题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=5016

https://loj.ac/problem/2254

题解

原式是这样的

\[\sum_{x = 0}^{\infty} get(l_1, r_1, x) \cdot get(l_2, r_2, x)
\]

因为一次询问需要用到两个区间,本来按理说最擅长两个区间的查询的主席树,这里也没有办法建立。

然后分块或者莫队的话也无能为力。

于是我们考虑对询问本身做一些修改,使得一次询问只涉及两个参数。


\[\sum_{x = 0}^{\infty} get(l_1, r_1, x) \cdot get(l_2, r_2, x)\\= \sum_{x=0}^{\infty} get(1, r_1, x) \cdot get(1, r_2, x) - get(1, l1 - 1, x) \cdot get(1, r2, x) - get(1, l2 - 1, x) \cdot get(1, r1, x) + get(1, l1 - 1, x) \cdot get(1, l2 - 1, x)
\]

这样,我们令 \(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]一个简单的询问 莫队的更多相关文章

  1. 【BZOJ5016】[Snoi2017]一个简单的询问 莫队

    [BZOJ5016][Snoi2017]一个简单的询问 Description 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计 ...

  2. 【bzoj5016】[Snoi2017]一个简单的询问 莫队算法

    题目描述 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次. 输入 第一行,一个数字N,表 ...

  3. Gym101138D Strange Queries/BZOJ5016 SNOI2017 一个简单的询问 莫队、前缀和、容斥

    传送门--Gym 传送门--BZOJ THUWC2019D1T1撞题可还行 以前有些人做过还问过我,但是我没有珍惜,直到进入考场才追悔莫及-- 设\(que_{i,j}\)表示询问\((1,i,1,j ...

  4. BZOJ5016:[SNOI2017]一个简单的询问(莫队)

    Description 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次. Input 第 ...

  5. [SNOI2017]一个简单的询问

    [SNOI2017]一个简单的询问 题目大意: 给定一个长度为\(n(n\le50000)\)的序列\(A(1\le A_i\le n)\),定义\(\operatorname{get}(l,r,x) ...

  6. BZOJ5016 Snoi2017一个简单的询问(莫队)

    容易想到区间转化成前缀和.这样每个询问有了二维坐标,莫队即可. #include<iostream> #include<cstdio> #include<cmath> ...

  7. [bzoj5016][Snoi2017]一个简单的询问

    来自FallDream的博客,未经允许,请勿转载,谢谢. 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出   get(l,r,x)表示计算区间[l,r]中 ...

  8. [SNOI2017]一个简单的询问【莫队+容斥原理】

    题目大意 给你一个数列,让你求两个区间内各个数出现次数的乘积的和. 分析 数据范围告诉我们可以用莫队过. 我并不知道什么曼哈顿什么乱七八糟的东西,但是我们可以用容斥原理将这个式子展开来. \[\sum ...

  9. 【LOJ2254】SNOI2017一个简单的询问

    莫队,每次询问的是两个区间,就把区间拆开,分开来算就好了. 借鉴了rank1大佬的玄学排询问的姿势. #include<bits/stdc++.h> #define N 50010 typ ...

随机推荐

  1. MacOS上zsh环境设置默认jdk

    进入home目录 cd ~ 修改.zprofile文件 vi .zprofile 按i进入vim插入模式,添加以下代码 export JAVA_HOME="/Library/Java/Jav ...

  2. MySQL的性能指标计算和优化方法

    MySQL的性能指标计算和优化方法1 QPS计算(每秒查询数) 针对MyISAM引擎为主的DB mysql> show global status like 'questions';+----- ...

  3. rime 同文输入法 安卓系统

    下载安装APP 从google play下载同文输入法 默认安装完只有3个输入法, 没有五笔和拼音 [官网][https://rime.im/download/] 获取五笔拼音方案 然后找到 /sdc ...

  4. 《HTML5 与 CSS3 基础教程(第 8 版)》

    第 1 章 网页的构造块 文件名和文件夹名 文件名全部使用小写字母,用短横线分隔单词,用 .html 作为扩展名.混合使用大小写字 母会增加访问者输入正确地址以及找到页面的难度 文件夹的名称也应全部用 ...

  5. EF2:Entity Mysql Sample

    1)概念 Entity Framework: 全称ADO.NET Entity Framework,是微软开发的基于ADO.NET的ORM(Object/Relational Mapping)框架.百 ...

  6. (转) intellij idea部署web项目时的位置(Tomcat)

    这篇文章说的比较好: 原文地址:https://blog.csdn.net/zmx729618/article/details/78340566 1.当你项目启动的时候console能看到项目运行的位 ...

  7. 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_02 泛型_1_泛型的概念

    ArrayList的源码,.在定义的时候用到了E这个E就是一个未知类型 ArrayList里面的add方法,参数也是E 包括我们之前常用的get方法 返回值也是E 类型什么时候可以确定呢?创建集合对象 ...

  8. adb之mokey的用法

    monkey是安卓稳定性的测试方向 目录 1.使用格式 2.一般命令 3.分析monkey日志 1.使用格式 monkey的固定使用模式如下:[adb shell] monkey [options] ...

  9. SQLServer中的top、MySql中的limit、Oracle中的rownum

    (1)在SQL Server中,我们使用 select top N * from tablename来查询tablename表中前N条记录. (2)在MySQL中,我们使用select * from ...

  10. Python工具库(感谢backlion整理)

    漏洞及渗透练习平台: WebGoat漏洞练习平台: https://github.com/WebGoat/WebGoat webgoat-legacy漏洞练习平台: https://github.co ...