题目传送门

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

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

几乎是双倍经验。

题解

对于第一道题目:

如果没有 \(a, b\) 这个区间的限制,那么这道题就是 bzoj1878 [SDOI2009]HH的项链

这道题虽然有 \(log\) 的做法,不过很多人应该都是拿这道题作为莫队的入门题的。


考虑如果带上范围限制怎么做。

一种显然的做法就是在莫队修改的时候用树状数组维护一下。但是复杂度 \(O(m\sqrt n \log n)\) GG。

我们需要一种能够 \(O(1)\) 进行修改,查询可以稍微慢一些的数据结构。

符合这个要求的只有分块。

于是做法就是 在莫队修改的时候用分块维护一下每一个权值块的和。


第二道题类似,只是需要多求一个某个区间某个范围的数的个数,一样求就可以了。


时间复杂度 \(O(m\sqrt n)\)。


Code bzoj3809

#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 = 100000 + 7;
const int M = 1000000 + 7;
const int B = 316 + 7; #define bl(x) (((x) - 1) / blo + 1)
#define st(x) (((x) - 1) * blo + 1)
#define ed(x) std::min((x) * blo, n) int n, m, blo, cnt;
int a[N], s[N], ans[N], ansb[N];
int ansc[M]; struct Query {
int l, r, a, b, *ans;
inline bool operator < (const Query &b) const { return bl(l) != bl(b.l) ? l < b.l : r < b.r; }
} q[M]; inline void qadd(int x, int k) {
ans[x] += k;
ansb[bl(x)] += k;
}
inline int qsum(int l, int r) {
int cnt = 0;
for (int i = l; i <= std::min(ed(bl(l)), r); ++i) cnt += ans[i];
for (int i = bl(l) + 1; i < bl(r); ++i) cnt += ansb[i];
if (bl(l) != bl(r)) for (int i = st(bl(r)); i <= r; ++i) cnt += ans[i];
return cnt;
} inline void madd(int x) {
++cnt;
++s[a[x]];
if (s[a[x]] == 1) qadd(a[x], 1);
}
inline void mdel(int x) {
++cnt;
--s[a[x]];
if (!s[a[x]]) qadd(a[x], -1);
} inline void work() {
std::sort(q + 1, q + m + 1);
int l = 1, r = 0;
for (int i = 1; i <= m; ++i) {
while (l > q[i].l) madd(--l);
while (r < q[i].r) madd(++r);
while (l < q[i].l) mdel(l++);
while (r > q[i].r) mdel(r--);
*q[i].ans = qsum(q[i].a, q[i].b);
// dbg("l = %d, r = %d: ", l, r);
// for (int i = 1; i <= n; ++i) dbg("%d%c", ans[i], " \n"[i == n]);
// if (i >= 106250) dbg("i = %d, cnt = %d\n", i, cnt);
}
for (int i = 1; i <= m; ++i) printf("%d\n", ansc[i]);
} inline void init() {
read(n), read(m);
blo = sqrt(n);
for (int i = 1; i <= n; ++i) read(a[i]);
for (int i = 1; i <= m; ++i) read(q[i].l), read(q[i].r), read(q[i].a), read(q[i].b), q[i].ans = ansc + i;
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

Code bzoj 3236

#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 = 100000 + 7;
const int M = 1000000 + 7;
const int B = 316 + 7; #define bl(x) (((x) - 1) / blo + 1)
#define st(x) (((x) - 1) * blo + 1)
#define ed(x) std::min((x) * blo, n) int n, m, blo;
int a[N], s[N], ans[N], ansb[N], ansa[N];
pii ansc[M]; struct Query {
int l, r, a, b;
pii *ans;
inline bool operator < (const Query &b) const { return bl(l) != bl(b.l) ? l < b.l : r < b.r; }
} q[M]; inline void qadd(int x, int k) {
ans[x] += k, ansa[bl(x)] += k;
if (ans[x] == 1 && k == 1) ++ansb[bl(x)];
if (ans[x] == 0 && k == -1) --ansb[bl(x)];
}
inline int qsumb(int l, int r) {
int cnt = 0;
for (int i = l; i <= std::min(ed(bl(l)), r); ++i) cnt += !!ans[i];
for (int i = bl(l) + 1; i < bl(r); ++i) cnt += ansb[i];
if (bl(l) != bl(r)) for (int i = st(bl(r)); i <= r; ++i) cnt += !!ans[i];
return cnt;
}
inline int qsuma(int l, int r) {
int cnt = 0;
for (int i = l; i <= std::min(ed(bl(l)), r); ++i) cnt += ans[i];
for (int i = bl(l) + 1; i < bl(r); ++i) cnt += ansa[i];
if (bl(l) != bl(r)) for (int i = st(bl(r)); i <= r; ++i) cnt += ans[i];
return cnt;
} inline void madd(int x) {
++s[a[x]];
qadd(a[x], 1);
}
inline void mdel(int x) {
--s[a[x]];
qadd(a[x], -1);
} inline void work() {
std::sort(q + 1, q + m + 1);
int l = 1, r = 0;
for (int i = 1; i <= m; ++i) {
while (l > q[i].l) madd(--l);
while (r < q[i].r) madd(++r);
while (l < q[i].l) mdel(l++);
while (r > q[i].r) mdel(r--);
*q[i].ans = pii(qsuma(q[i].a, q[i].b), qsumb(q[i].a, q[i].b));
// dbg("l = %d, r = %d: ", l, r);
// for (int i = 1; i <= n; ++i) dbg("%d%c", ans[i], " \n"[i == n]);
// if (i >= 106250) dbg("i = %d, cnt = %d\n", i, cnt);
}
for (int i = 1; i <= m; ++i) printf("%d %d\n", ansc[i].fi, ansc[i].se);
} inline void init() {
read(n), read(m);
blo = sqrt(n);
for (int i = 1; i <= n; ++i) read(a[i]);
for (int i = 1; i <= m; ++i) read(q[i].l), read(q[i].r), read(q[i].a), read(q[i].b), q[i].ans = ansc + i;
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

bzoj3809 Gty的二逼妹子序列 & bzoj3236 [Ahoi2013]作业 莫队+分块的更多相关文章

  1. [bzoj3809]Gty的二逼妹子序列/[bzoj3236][Ahoi2013]作业

    [bzoj3809]Gty的二逼妹子序列/[bzoj3236][Ahoi2013]作业 bzoj   bzoj 题目大意:一个序列,m个询问在$[l,r]$区间的$[x,y]$范围内的数的个数/种类. ...

  2. BZOJ 3809: Gty的二逼妹子序列 & 3236: [Ahoi2013]作业 [莫队]

    题意: 询问区间权值在$[a,b]$范围内种类数和个数 莫队 权值分块维护种类数和个数$O(1)-O(\sqrt{N})$ #include <iostream> #include < ...

  3. BZOJ_3809_Gty的二逼妹子序列 && BZOJ_3236_[Ahoi2013]作业 _莫队+分块

    BZOJ_3809_Gty的二逼妹子序列 && BZOJ_3236_[Ahoi2013]作业 _莫队+分块 Description Autumn和Bakser又在研究Gty的妹子序列了 ...

  4. [bzoj3809]Gty的二逼妹子序列_莫队_分块

    Gty的二逼妹子序列 bzoj-3809 题目大意:给定一个n个正整数的序列,m次询问.每次询问一个区间$l_i$到$r_i$中,权值在$a_i$到$b_i$之间的数有多少个. 注释:$1\le n\ ...

  5. BZOJ3809: Gty的二逼妹子序列

    Description Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题.   对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数.   为了方 ...

  6. [BZOJ3809]Gty的二逼妹子序列[莫队+分块]

    题意 给出长度为 \(n\) 的序列,\(m\) 次询问,每次给出 \(l,r,a,b\) ,表示询问区间 \([l,r]\) 中,权值在 \([a,b]\) 范围的数的种类数. \(n\leq 10 ...

  7. 2019.01.08 bzoj3809: Gty的二逼妹子序列(莫队+权值分块)

    传送门 题意:多组询问,问区间[l,r]中权值在[a,b]间的数的种类数. 看了一眼大家应该都知道要莫队了吧. 然后很容易想到用树状数组优化修改和查询做到O(mnlogamax)O(m\sqrt nl ...

  8. 【莫队算法】【权值分块】bzoj3809 Gty的二逼妹子序列

    如题. #include<cstdio> #include<algorithm> #include<cmath> using namespace std; int ...

  9. BZOJ3236:[AHOI2013]作业(莫队,分块)

    Description Input Output Sample Input 3 4 1 2 2 1 2 1 3 1 2 1 1 1 3 1 3 2 3 2 3 Sample Output 2 2 1 ...

随机推荐

  1. React-Native 之 GD (十三)数据持久化(realm) 及 公共Cell

    1.数据持久化 数据持久化是移动端的一个重要部分,刚发现 Realm 原来已经支持 React-Native 了 步骤一: 引入 realm $ npm install realm --save 步骤 ...

  2. selinux的设置包括两个部分: 修改安全上下文和修改策略

    selinux的设置包括两个部分: 修改安全上下文和修改策略 修改安全上下文: chcon = change context: chcon 修改策略: setsebool 策略就是由很多boo类型的变 ...

  3. 阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节 常用函数接口_16_常用的函数式接口_Function接口中练习-自定义函数模型拼接

  4. 封装好日志的类 logging

    import logging from logging import handlers class MyLogger(): def __init__(self,file_name,level='inf ...

  5. Jmeter之Switch Controller

    在测试过程中,各种不同的情况需要执行不同的操作,这个时候用if控制器比较麻烦,此时就可以使用Switch Controller代替. 一.界面显示 二.配置说明 1.名称:标识 2.注释:备注 3.S ...

  6. Good teachers,they inspire you, they entertain you,and you end up learning a ton even when you don't know it.

    pardon. v. 原谅.抱歉.再说一次 honourable.adj.值得钦佩的 specification.n.规格.标准 amongst.prep.在...中 gallon.n.加仑 comp ...

  7. SpringBoot中FreeMarker创建

    1.创建SpringBoot项目时,勾选freemarker依赖(web,dev) 2.Controller中向model中存放数据 package com.ziv.springbootbygrald ...

  8. NOPI导入导出EXCEL

    一.简介 1. 什么是NPOI NPOI,顾名思义,就是POI的.NET版本.那POI又是什么呢?POI是一套用Java写成的库,能够帮助开发者在没有安装微软Office的情况下读写Office 97 ...

  9. Node.js实战11:fs模块初探。

    fs模块封装了对文件操作的各种方法,比如同步和异步读写.批量操作.流.监听. 我们还是通常例程学习, 获取目录下的文件清单: var fs =require("fs"); fs.r ...

  10. linux下的dd命令使用详解

    一.dd命令的解释 dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意:指定数字的地方若以下列字符结尾,则乘以相应的数字:b=512:c=1:k=1024:w=2 参数注释: 1. ...