博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[洛谷P4688][Ynoi2016]掉进兔子洞
阅读量:7065 次
发布时间:2019-06-28

本文共 2369 字,大约阅读时间需要 7 分钟。

题目大意:给定一个$n(n\leqslant10^5)$序列,$m(m\leqslant10^5)$个询问,每个询问给出$l_1,r_1,l_2,r_2,l_3,r_3$。令$s$为该三个区间的交集的大小,则输出$|[l_1,r_1]|+|[l_2,r_2]|+|[l_3,r_3]|−3|s|$

题解:$|[l_1,r_1]|+|[l_2,r_2]|+|[l_3,r_3]|$这一部分比较好求,主要就是求$|s|$,$s$是这三个区间元素的并集,可以想到用$bitset$,但是$bitset$似乎只可以求有多少种相同元素,而不可以求有多少个相同元素,这时可以改一下离散化的方式,排序后不要去重,这时就可以用这个数和这个数现在已经出现的次数定下一个唯一确定位置。这样就可以完成求并集的过程了。

这里可以用莫队来求每个数出现次数以及那一个元素出现的集合。但是发现空间复杂度是$O(\dfrac{nm}{\omega})$,开不下。可以把询问分成$3$次进行处理,就可以了

卡点:把一个$maxm$打成了$maxn$,然后$RE$

 

C++ Code:

#include 
#include
#include
#include
#include
namespace __IO { namespace R { int x, ch; inline int read() { while (isspace(ch = getchar())); for (x = ch & 15; isdigit(ch = getchar()); ) x = x * 10 + (ch & 15); return x; } }}using __IO::R::read;#define maxn 100010#define maxm 35000int n, m;int s[maxn], v[maxn];std::bitset
ans[maxm + 10], res;struct Query { int l, r, id; inline friend bool operator < (const Query &lhs, const Query &rhs) { return lhs.l >> 8 == rhs.l >> 8 ? (lhs.l >> 8 & 1 ? lhs.r > rhs.r : lhs.r < rhs.r) : lhs.l < rhs.l; }} q[maxm * 3 + 10];int tmpans[maxm + 10], cnt[maxn];inline void add(int x) {res.set(x + cnt[x]); cnt[x]++;}inline void del(int x) {cnt[x]--; res.reset(x + cnt[x]);}void solve() { int tot = 0; for (int i = 1; m && i < maxm; i++, m--) { ans[i].set(); tmpans[i] = 0; q[++tot].id = i, q[tot].l = read(), q[tot].r = read(), tmpans[i] += q[tot].r - q[tot].l + 1; q[++tot].id = i, q[tot].l = read(), q[tot].r = read(), tmpans[i] += q[tot].r - q[tot].l + 1; q[++tot].id = i, q[tot].l = read(), q[tot].r = read(), tmpans[i] += q[tot].r - q[tot].l + 1; } res.reset(); for (int i = 1; i <= n; i++) cnt[i] = 0; int l = 1, r = 0; std::sort(q + 1, q + tot + 1); for (int i = 1; i <= tot; i++) { while (r < q[i].r) add(s[++r]); while (l > q[i].l) add(s[--l]); while (r > q[i].r) del(s[r--]); while (l < q[i].l) del(s[l++]); ans[q[i].id] &= res; } const int M = tot / 3; for (int i = 1; i <= M; i++) printf("%d\n", tmpans[i] - ans[i].count() * 3);}int main() { n = read(), m = read(); for (int i = 1; i <= n; i++) v[i] = s[i] = read(); std::sort(v + 1, v + n + 1); for (int i = 1; i <= n; i++) s[i] = std::lower_bound(v + 1, v + n + 1, s[i]) - v; while (m) solve(); return 0;}

  

转载于:https://www.cnblogs.com/Memory-of-winter/p/10120966.html

你可能感兴趣的文章
java json转抽象对象_java Bean与json对象间的转换实例讲解
查看>>
java to vb converter_VB源码转换工具(VBto Converter)
查看>>
centos 6.5 编译php mysql5.6_CentOS 6.5编译安装Nginx+MySQL+PHP
查看>>
怎么用php配合js编写动态页面_关于php动态页面的实例汇总
查看>>
sublime2 php,在 Sublime Text 2 中运行 PHP
查看>>
php外部脚本,php的exec()函数执行外部Linux脚本问题
查看>>
php工作日,php计算N个工作日之后的方法
查看>>
php读取配置文件连接mysql数据库,xml作mysql的配置文件及php对配置文件信息的读取 连接数据库...
查看>>
java培训每日总结,java培训第二天总结
查看>>
php 截取第一个中文,php中截取单个中文
查看>>
java备忘录模式 类图,折腾Java设计模式之备忘录模式
查看>>
php push key value,php操作redis常见方法示例【key与value操作】
查看>>
php获取函数名字后缀,php 获取文件后缀名,并判断是否合法的函数
查看>>
php 播放程序,PHP音乐播放程序
查看>>
php 删除文件的函数,PHP 删除文件函数是什么
查看>>
php xmp,xmp1和2模式区别有哪些
查看>>
java随机矩阵,Spark-RSVD:Spark大型稀疏矩阵随机奇异值分解库
查看>>
php++简单左侧导航,简单的jquery左侧导航栏和页面选中效果_jquery
查看>>
29岁零基础学php,零基础学PHP,从入门到精通
查看>>
真因数之和编程matlab,真因数
查看>>