题目传送门

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})\)。这样写复杂度似乎不是很标准,因为复杂度里面不应该有任何常数。

  1. #include<bits/stdc++.h>
  2. #define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
  3. #define dbg(...) fprintf(stderr, __VA_ARGS__)
  4. #define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
  5. #define fi first
  6. #define se second
  7. #define pb push_back
  8. template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
  9. template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}
  10. typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
  11. template<typename I> inline void read(I &x) {
  12. int f = 0, c;
  13. while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
  14. x = c & 15;
  15. while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
  16. f ? x = -x : 0;
  17. }
  18. const int N = 50000 + 7;
  19. #define bl(x) (((x) - 1) / blo + 1)
  20. int n, m, blo, Q;
  21. ll val;
  22. int a[N], cl[N], cr[N];
  23. ll ans[N];
  24. struct Query {
  25. int opt, l, r;
  26. ll *ans;
  27. inline Query() {}
  28. inline Query(const int &opt, const int &l, const int &r, ll *ans) : opt(opt), l(l), r(r), ans(ans) {
  29. if (l > r) std::swap(this->l, this->r);
  30. }
  31. inline bool operator < (const Query &b) const { return bl(l) != bl(b.l) ? l < b.l : r < b.r; }
  32. } q[N << 2];
  33. inline void addl(int x) {
  34. val += cr[a[x]];
  35. ++cl[a[x]];
  36. }
  37. inline void addr(int x) {
  38. val += cl[a[x]];
  39. ++cr[a[x]];
  40. }
  41. inline void dell(int x) {
  42. val -= cr[a[x]];
  43. --cl[a[x]];
  44. }
  45. inline void delr(int x) {
  46. val -= cl[a[x]];
  47. --cr[a[x]];
  48. }
  49. inline void work() {
  50. blo = sqrt(Q);
  51. std::sort(q + 1, q + Q + 1);
  52. int l = 0, r = 0;
  53. for (int i = 1; i <= Q; ++i) {
  54. while (r < q[i].r) addr(++r);
  55. while (l < q[i].l) addl(++l);
  56. while (l > q[i].l) dell(l--);
  57. while (r > q[i].r) delr(r--);
  58. *q[i].ans += q[i].opt * val;
  59. }
  60. for (int i = 1; i <= m; ++i) printf("%lld\n", ans[i]);
  61. }
  62. inline void init() {
  63. read(n);
  64. for (int i = 1; i <= n; ++i) read(a[i]);
  65. read(m);
  66. for (int i = 1; i <= m; ++i) {
  67. int l1, r1, l2, r2;
  68. read(l1), read(r1), read(l2), read(r2);
  69. q[++Q] = Query(1, r1, r2, ans + i);
  70. if (l2 > 1) q[++Q] = Query(-1, l2 - 1, r1, ans + i);
  71. if (l1 > 1) q[++Q] = Query(-1, l1 - 1, r2, ans + i);
  72. if (l1 > 1 && l2 > 1) q[++Q] = Query(1, l1 - 1, l2 - 1, ans + i);
  73. }
  74. }
  75. int main() {
  76. #ifdef hzhkk
  77. freopen("hkk.in", "r", stdin);
  78. #endif
  79. init();
  80. work();
  81. fclose(stdin), fclose(stdout);
  82. return 0;
  83. }

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. Cocoapods 版本

    查看当前安装的版本 gem list 卸载版本 gem uninstall cocoapods 安装 gem install cocoapods gem install cocoapods -v 1. ...

  2. windows编程,消息函数中拦截消息的问题

    很多年没有写windows窗口程序了,今天自制基于vulkan的程序时遇到了一些问题,部分代码如下: LRESULT CALLBACK XWindow::WndProc(HWND hWnd, UINT ...

  3. Android Build System Ultimate Guide

    Android Build System Ultimate Guide April 8,2013 Lately, Android Open Source Project has gone throug ...

  4. JS new date在IOS出现的问题

    实例代码: input = input.replace(/\-/g, "/");//横杠的时间不能被识别,所以要替换程斜杠 let time = new Date(input); ...

  5. Denali NAND FLASH控制器的验证

    NAND FLASH的结构如图所示: Denali NAND FLASH控制器模块提供了从AHB总线到外部NAND FLASH存储器芯片IO管脚的访问功能.主要技术特性包括: 1.标准32位AHB总线 ...

  6. javascript 动态修改css样式方法汇总(四种方法)

    在很多情况下,都需要对网页上元素的样式进行动态的修改.在JavaScript中提供几种方式动态的修改样式,下面将介绍方法的使用.效果.以及缺陷. 1.使用obj.className来修改样式表的类名. ...

  7. vCenter 部件关系简介 & 网络原理

    目录 目录 主机和集群 vCenter Datacenter Cluster Host Virtual Machine Folder Resource Pool Template 数据存储 Datas ...

  8. javascript 跳出循环比较

    for continue 跳出当前循环,继续下一个循环 break 结束循环 forEach 不能使用continue , break return/return false 跳出当前循环,在forE ...

  9. json 格式

    Json格式规则:(Douglas Crockford提出的) 1) 并列的数据之间用逗号(“,”)分隔. 2) 映射用冒号(“:”)表示. 3) 并列数据的集合(数组)用方括号("[]&q ...

  10. 【ABAP系列】SAP ABAP POPUP弹出框自建内容

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP ABAP POPUP弹出框自 ...