题目传送门

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. vue-router 2.0 跳转之router.push()

    router.push(location) 除了使用 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现. router.push(location) 想要导航 ...

  2. centos php 安装 decrypt

    CentOS php Fatal error: Call to undefined function mcrypt_decrypt() // yum安装没有 #yum install libmcryp ...

  3. SQL优化—nested loop优化

    跑批时间段22:00-23:00,生成AWR报告 分析sql:SQL_ID='5hfw4smzs2pqw' 执行计划: SQL> select *  FROM TABLE(DBMS_XPLAN. ...

  4. P1080国王游戏

    传送 最大值最小什么的一看就是二分了qwq 然鹅并不知道怎么检查,所以我们换个思路 我们要求出最小的最大值,这肯定和大臣的排列有关,会不会有什么规律? 先看看只有两个大臣的情况 排列:1 2,ans1 ...

  5. HDFS——完全分布式搭建

    架构 NN--namenode SNN--secondnamenode DN--datanode hadoop_env.sh中修改JAVA_HOME core-site.xml <propert ...

  6. 《图解设计模式》读书笔记8-3 STATE模式

    目录 State模式 示例程序 实现的功能 不使用&使用状态模式对比 示例程序的类图 代码 角色和类图 角色 类图 拓展思路 分而治之 依赖于状态的处理 谁来管理状态迁移 易于增加新状态 实例 ...

  7. linux启动内核源码分析

    内核的启动时从main.c这个文件里面的start_kernel函数开始的,这个文件在linux源码里面的init文件夹下面 下面我们来看看这个函数 这个函数很长,可以看个大概过去 asmlinkag ...

  8. Myeclipse 快捷键大全(绝对全)

    非常感谢分享这篇文章的大虾..但是我忘了几下您的blog地址,因此无法注明原文地址...见谅哈 存盘 Ctrl+s(肯定知道) 注释代码 Ctrl+/ 取消注释 Ctrl+\(Eclipse3已经都合 ...

  9. [Python3] 010 字符串:给你们看看我的内置方法 第二弹

    目录 少废话,上例子 1. isidentifier() 2. islower() 3. isnumeric() 4. isprintable() 5. isspace() 6. istitle() ...

  10. RocketMQ的消息发送及消费

    RocketMQ消息支持的模式: 消息支持的模式分为三种:NormalProducer(普通同步),消息异步发送,OneWay. 消息同步发送: 普通消息的发送和接收在前面已经演示过了,在前面的案例中 ...