此题的询问是一个位置和权值都有限制的二维区间,但是题目具备无修改和允许离线两个条件,可以用莫队算法解决。
一个想法是:用莫队维护位置,树状数组维护权值。
具体的说,用一个数组 cnt cnt,维护莫队当前到达的位置区间内每个值的出现次数,并用两个树状数组,一个维护 cnt cnt的前缀和,另一个维护对于所有的 j∈[1,i] j\in[1,i], cnt[j]>0 cnt[j]>0的个数。
莫队移动指针时,以位置区间 [l,r] [l,r]转移到 [l,r+1] [l,r+1]为例:
记位置 r+1 r+1上的值为 x x,则cnt[x]cnt[x]加一,并且在第一个树状数组的第 x x个位置加11。此时,还要判断如果现在 cnt[x]=1 cnt[x]=1,则第二个树状数组的第 x x个位置也要加11。
这样,第一个树状数组的区间 [a,b] [a,b]之和就是第一问的结果,第二个树状数组的区间 [a,b] [a,b]之和就是第二问的结果。
复杂度 O((m+n)n−−√logn O((m+n)\sqrt{n}\log n。此外,还有一种 O((m+n)n−−√) O((m+n)\sqrt{n})的神奇的分块做法……
代码:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 5, M = 1e6 + 5;
int n, m, sq, a[N], S[N], T[N], cnt[N], res1[M], res2[M];
struct cyx {int id, l, r, a, b, bl;} que[M];
bool comp(cyx a, cyx b) {if (a.bl != b.bl) return a.bl < b.bl;return a.r < b.r;
}
int lowbit(int x) {return x & -x;}
void changeS(int x, int v) {for (; x <= n; x += lowbit(x))S[x] += v;
}
int askS(int x) {int res = 0;for (; x; x -= lowbit(x))res += S[x];return res;
}
void changeT(int x, int v) {for (; x <= n; x += lowbit(x))T[x] += v;
}
int askT(int x) {int res = 0;for (; x; x -= lowbit(x))res += T[x];return res;
}
inline int read() {int res = 0; bool bo = 0; char c;while (((c = getchar()) < '0' || c > '9') && c != '-');if (c == '-') bo = 1; else res = c - 48;while ((c = getchar()) >= '0' && c <= '9')res = (res << 3) + (res << 1) + (c - 48);return bo ? ~res + 1 : res;
}
int main() {int i; n = read(); m = read(); sq = sqrt(n);for (i = 1; i <= n; i++) a[i] = read();for (i = 1; i <= m; i++) {que[i].l = read(); que[i].r = read();que[i].a = read(); que[i].b = read();que[i].id = i; que[i].bl = (que[i].l - 1) / sq + 1;}sort(que + 1, que + m + 1, comp);for (i = que[1].l; i <= que[1].r; i++) {changeS(a[i], 1); cnt[a[i]]++;if (cnt[a[i]] == 1) changeT(a[i], 1);}res1[que[1].id] = askS(que[1].b) - askS(que[1].a - 1);res2[que[1].id] = askT(que[1].b) - askT(que[1].a - 1);for (i = 2; i <= m; i++) {int tl = que[i - 1].l, tr = que[i - 1].r,vl = que[i].l, vr = que[i].r;while (tl > vl) {changeS(a[--tl], 1); cnt[a[tl]]++;if (cnt[a[tl]] == 1) changeT(a[tl], 1);}while (tr < vr) {changeS(a[++tr], 1); cnt[a[tr]]++;if (cnt[a[tr]] == 1) changeT(a[tr], 1);}while (tl < vl) {changeS(a[tl++], -1); cnt[a[tl - 1]]--;if (!cnt[a[tl - 1]]) changeT(a[tl - 1], -1);}while (tr > vr) {changeS(a[tr--], -1); cnt[a[tr + 1]]--;if (!cnt[a[tr + 1]]) changeT(a[tr + 1], -1);}res1[que[i].id] = askS(que[i].b) - askS(que[i].a - 1);res2[que[i].id] = askT(que[i].b) - askT(que[i].a - 1);}for (i = 1; i <= m; i++) printf("%d %d\n", res1[i], res2[i]);fclose(stdin); fclose(stdout);return 0;
}

[BZOJ3236][Ahoi2013]作业(莫队+树状数组)相关推荐

  1. BZOJ3236[Ahoi2013]作业——莫队+树状数组/莫队+分块

    题目描述 输入 输出 样例输入 3 4 1 2 2 1 2 1 3 1 2 1 1 1 3 1 3 2 3 2 3 样例输出 2 2 1 1 3 2 2 1 提示 N=100000,M=1000000 ...

  2. HDU多校1 - 6959 zoto(莫队+树状数组/值域分块)

    题目链接:点击查看 题目大意:在二维平面内有 nnn 个点,表示为 (i,f[i])(i,f[i])(i,f[i]),需要回答 mmm 次询问,每次询问会给出一个矩形,问矩形内有多少个不同的 yyy ...

  3. Bzoj3236:[Ahoi2013]作业:莫队算法+树状数组

    题目链接:3236:[Ahoi2013]作业 这题-- 很水的一道莫队,只要用一个树状数组维护数值出现的前缀和就行就行 然而-- 可怜的我真是T得蛋疼了QAQ 先是写了一发裸莫队,T 卧槽T了? 快速 ...

  4. BZOJ-3289-Mato的文件管理-莫队+树状数组

    描述 给定一段 n(n≤50000) 个数的序列, m(m≤50000) 次询问 [L, R] 区间内相邻元素两两交换使得序列不降的最少次数. 分析 首先转化为一个逆序对的问题, 最少交换的次数就是逆 ...

  5. BZOJ 3289 Mato的文件管理 | 莫队 树状数组

    BZOJ 3289 Mato的文件管理 题意 求区间逆序对. 题解 在莫队的基础上使用树状数组求逆序对. 在当前区间左侧加入一个数时,res += 原区间比它小的数的个数: 在当前区间右侧加入一个数时 ...

  6. HH的项链 HYSBZ - 1878 (莫队/ 树状数组)

    HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一 段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此他的项链变得越来越长.有一天,他突然 ...

  7. HDU 4417 Super Mario(莫队 + 树状数组 + 离散化)

    Super Mario 思路 区间查找问题,容易想到离线莫队,确实这题就是莫队,接下来我们考虑如何维护区间高度值问题. 既然是离线嘛,我们容易想到离散化和他挂钩,想想这题是否需要离散化,高度的最大值是 ...

  8. Bzoj 3289: Mato的文件管理 莫队,树状数组,逆序对,离散化,分块

    3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MB Submit: 1539  Solved: 665 [Submit][Status][ ...

  9. 【BZOJ3289】Mato的文件管理,莫队+树状数组

    Time:2016.09.07 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: 这个题意就是让你求[l,r]的逆序对数 暴力做的话是O(Qn2)O(Qn^2)或O(Qnlogn)O( ...

最新文章

  1. springBoot 在线心理咨询管理系统
  2. 《Linux 性能及调优指南》1.6 了解Linux性能指标
  3. 素数筛选-hdu2710
  4. 快评《19家网站内容低俗被曝光》
  5. 盘点Win10系统的实用“小设计”
  6. PAT (Basic Level) Practise 1045 快速排序(离散化+主席树区间内的区间求和)
  7. mysql按月归档日志表
  8. Nervos DAO锁定总额突破100亿,近日解锁的14.28亿生态基金已被全部存入
  9. 初步了解python
  10. eclipse adt 安卓开发配置
  11. 优雅地解决Visio图片插入word中虚线变实线的问题
  12. 刘宇凡:我是一只特立独行的猪
  13. IDEA无法启动:error launching idea (Failed to create JVM )
  14. Smali语法学习三
  15. Java常用工具类-发短信(集成阿里云短信服务)
  16. 岗位po是什么意思_通信公司中PO和PM分别是什么意思?
  17. 介绍一款数据库管理工具-DBeaver
  18. Spring实战笔记——(1)Spring之旅(上)
  19. 二叉树遍历与java实现
  20. 操作系统——索引分配

热门文章

  1. js树形结构数组扁平化
  2. python每条语句以什么结尾_c语言每条语句以什么结束
  3. stm32L151 系统时钟配置
  4. 常用Linux Shell命令
  5. vscode如何选择写HTML还是css,什么是HTML和CSS,vscode编辑器
  6. LLVM ERROR out of memory
  7. 移动网络技术--名词介绍
  8. K8s中pv和pvc的使用
  9. 03 如何透彻理解 Paxos 算法?
  10. 一文帮你搞懂GBK码协议,让你真正理解和搞定它!