【cdq分治】【CF1093E】 Intersection of Permutations
果然前两天写完咕咕咕那个题的题解以后博客就开始咕咕咕了……
Description
给定整数 \(n\) 和两个 \(1~\sim~n\) 的排列 \(A,B\)。
\(m\) 个操作,操作有两种:
- \(1~,~l1~,~r1~,~l2~,~r2\) 求\((\bigcup_{i=l1}^{r1} A_i)~\bigcap~(\bigcup_{i=l2}^{r2} B_i)\)
- \(2~,~x~,~y\) 交换 \(B_x,~B_y\)
Input
第一行是两个正整数 \(n,m\)
下面两行,每行 \(n\) 个数, 给出排列 \(A,B\)
下面 \(m\) 行,每行一个操作
Output
对每个询问输出一行代表答案
Hint
\(0~\leq~n,m~\leq~2~\times~10^5\)
Solution
这不是hash+二维树状数组好题嘛!
然而因为一次操作有 \(4\) 次查询,相当于操作次数 \(10^6\),hash树状数组显然过不去= =
考虑如果给 \(B\) 重编号,\(B_i\) 代表原 \(B\) 中第 \(i\) 个元素在 \(A\) 中出现的位置,那么每次查询就等价于区间 \([l2, r2]\) 中有多少个数在 \([l1,r1]\) 内。于是这个问题被转化成了一个二维数点问题那我们去写hash+树状数组吧!,并且资瓷离线,于是考虑cdq分治过掉
这里记录一下待修改的cdq怎么写:将一次修改操作改为一个添加操作和一个删除操作。例如,交换 \(x, y\) 等价于删除 \((x,B_x),(y,B_y)\),并且加入 \((x,B_y),(y,B_x)\)。初始的序列以添加的形式给出
于是复杂度 \(O(n\log^2n)\),可以过掉本题
Code
#include <cstdio>
#include <algorithm>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#endif
#define rg register
#define ci const int
#define cl const long long
typedef long long int ll;
namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
}
template <typename T>
inline void qr(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
}
template <typename T>
inline void ReadDb(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
if (ch == '.') {
ch = IPT::GetChar();
double base = 1;
while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
}
if (lst == '-') x = -x;
}
namespace OPT {
char buf[120];
}
template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
rg int top=0;
do {OPT::buf[++top] = x % 10 + '0';} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
}
const int maxn = 200010;
const int maxt = 1000010;
struct Zay {
int id, x, y, mul, oppt, vec;
inline void setit(ci _a, ci _b, ci _c, ci _d, ci _e, ci _f) {
id = _a; x = _b; y = _c; mul = _d; oppt = _e; vec = _f;
}
};
Zay opt[maxt], temp[maxt];
inline int lowbit(ci &x) {return x & -x;}
int n, m, cnt, tot;
int CU[maxn], MU[maxn], ans[maxn], tree[maxt];
int ask(int);
void cdq(ci, ci);
void add(int, ci);
void query(const Zay&);
void update(const Zay&);
int main() {
freopen("1.in", "r", stdin);
qr(n); qr(m);
int a, l1, r1, l2, r2;
for (rg int i = 1; i <= n; ++i) {
a = 0; qr(a); CU[a] = i;
}
for (rg int i = 1; i <= n; ++i) {
a = 0; qr(a);// printf("QWQ%d\n", a);
++cnt; opt[cnt] = (Zay){opt[cnt - 1].id + 1, i, MU[i] = CU[a], 1, 0, 0};
}
while (m--) {
a = 0; qr(a);//printf("EM%d\n", a);
if (a == 1) {
l1 = r1 = l2 = r2 = 0; qr(l1); qr(r1); qr(l2); qr(r2); --l1; --l2;
int _pre = opt[cnt].id + 1;
opt[++cnt].setit(_pre, r2, r1, 1, 1, ++tot);
opt[++cnt].setit(_pre, l2, r1, -1, 1, tot);
opt[++cnt].setit(_pre, l2, l1, 1, 1, tot);
opt[++cnt].setit(_pre, r2, l1, -1, 1, tot);
} else {
l1 = r1 = 0; qr(l1); qr(r1);
int _pre = opt[cnt].id + 1;
opt[++cnt].setit(_pre, l1, MU[l1], -1, 0, 0);
opt[++cnt].setit(_pre, r1, MU[r1], -1, 0, 0);
std::swap(MU[l1], MU[r1]);
opt[++cnt].setit(_pre, l1, MU[l1], 1, 0, 0);
opt[++cnt].setit(_pre, r1, MU[r1], 1, 0, 0);
}
}
cdq(1, cnt);
for (rg int i = 1; i <= tot; ++i) qw(ans[i], '\n', true);
return 0;
}
void cdq(ci l, ci r) {
if (l == r) return;
int mid = (l + r) >> 1;
cdq(l, mid); cdq(mid + 1, r);
for (rg int i = l, ll = l, rr = mid + 1; i <= r; ++i) {
if (ll > mid) {
query(opt[rr]);
temp[i] = opt[rr++];
} else if (rr > r) {
update(opt[ll]);
temp[i] = opt[ll++];
} else if (opt[ll].x <= opt[rr].x) {
update(opt[ll]);
temp[i] = opt[ll++];
} else {
query(opt[rr]);
temp[i] = opt[rr++];
}
}
for (rg int i = l; i <= mid; ++i) if (!opt[i].oppt) {
add(opt[i].y, -opt[i].mul);
}
for (rg int i = l; i <= r; ++i) opt[i] = temp[i];
}
inline void update(const Zay &_t) {
if (_t.oppt) return;
add(_t.y, _t.mul);
}
inline void query(const Zay &_t) {
if (!_t.oppt) return;
ans[_t.vec] += _t.mul * ask(_t.y);
}
void add(int x, ci v) {
while (x <= n) {
tree[x] += v;
x += lowbit(x);
}
}
int ask(int x) {
int _ret = 0;
while (x) {
_ret += tree[x];
x -= lowbit(x);
}
return _ret;
}
Summary
cdq处理带修问题时,将修改变为删除和插入。
【cdq分治】【CF1093E】 Intersection of Permutations的更多相关文章
- [CF1093E]Intersection of Permutations
[CF1093E]Intersection of Permutations 题目大意: 给定两个长度为\(n(n\le2\times10^5)\)的排列\(A,B\).\(m(m\le2\times1 ...
- CF1093E Intersection of Permutations 树状数组套权值线段树
\(\color{#0066ff}{ 题目描述 }\) 给定整数 \(n\) 和两个 \(1,\dots,n\) 的排列 \(a,b\). \(m\) 个操作,操作有两种: \(1\ l_a\ r_a ...
- [CF1093E]Intersection of Permutations:树套树+pbds
分析 裸的二维数点,博主用树状数组套平衡树写的,顺便pbds真好用. Update on 2018/12/20:再解释一下为什么是二维数点,第一维是\(la \leq i \leq ra\),第二维是 ...
- CF1093E Intersection of Permutations [分块 +bitset]
大家好, 我非常喜欢暴力数据结构, 于是就用分块A了此题 分块题,考虑前缀和 \(b_i\) 表示 bitset 即 \(0\) ~ $i $ 出现过的数字,然后考虑直接暴力复制块然后前缀和,修改也很 ...
- CF 1093E Intersection of Permutations——CDQ分治
题目:http://codeforces.com/contest/1093/problem/E 只能想到转化成查询一个区间里值在一个范围里的数的个数…… 没有想到这样适合用主席树套树状数组维护.不过据 ...
- Codeforces 1093E Intersection of Permutations [CDQ分治]
洛谷 Codeforces 思路 一开始想到莫队+bitset,发现要T. 再想到分块+bitset,脑子一抽竟然直接开始写了,当然也T了. 最后发现这就是个裸的CDQ分治-- 发现\(a\)不变,可 ...
- Codeforces 1093E Intersection of Permutations (CDQ分治+树状数组)
题意:给你两个数组a和b,a,b都是一个n的全排列:有两种操作:一种是询问区间在数组a的区间[l1,r1]和数组b的区间[l2,r2]出现了多少相同的数字,另一种是交换数组b中x位置和y位置的数字. ...
- CF 1093 E. Intersection of Permutations
E. Intersection of Permutations 链接 题意: 给定两个序列,询问第一个排列的[l1,r1]和第二个排列[l2,r2]中有多少个共同的数,支持在第二个排列中交换两个数. ...
- HDU5322 Hope(DP + CDQ分治 + NTT)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5322 Description Hope is a good thing, which can ...
随机推荐
- 自己动手做AI:Google AIY开发工具包解析
2018年国际消费性电子展(CES)上,最明显的一个趋势是Amazon与Google的语音技术进驻战,如AmazonAlexa进驻到Acer笔电内,Google Assist进驻到KIA汽车内,其他如 ...
- 003--MySQL 数据库事务
什么是事务? 事务是一组原子性的 SQL 查询, 或者说是一个独立的工作单元. 在事务内的语句, 要么全部执行成功, 要么全部执行失败. 事务的 ACID 性质 数据库事务拥有以下四个特性, 即 AC ...
- 高可用Kubernetes集群-4. kubectl客户端工具
六.部署kubectl客户端工具 1. 下载 [root@kubenode1 ~]# cd /usr/local/src/ [root@kubenode1 src]# wget https://sto ...
- mongodb4简明笔记
就一数据库,掌握基本用法,其他的现学现卖就行了. 所以要把握基本套路. 创建数据库=>使用数据库=>创建集合=>使用集合=>创建文档=>使用文档 1.数据库 mongod ...
- Hibernate入门篇<1>hibernate.cfg.xml学习小结
Hibernate配置文件主要用于配置数据库连接和Hibernate运行时所需的各种属性,这个配置文件应该位于应用程序或Web程序的类文件夹 classes中.Hibernate配置文件支持两种形式, ...
- 安装cocoa pods
1.移除现有Ruby默认源 $gem sources --remove https://rubygems.org/ 2.使用新的源 $gem sources -a https://ruby.taoba ...
- 2018软工实践—Alpha冲刺(6)
队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭鸭鸭鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作 测试服务器并行能力 学习MSI.CUDA ...
- 软工实践-Alpha 冲刺 (9/10)
队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 已经解决登录注册等基本功能的界面. 完成非功能的主界面制作 ...
- 关《我是IT小小鸟》有感
我一直认为大学就是一个自由的舒适的学习环境,没有人可以干扰你限制你,以至于我到了大学之后只剩下了颓废的生活.每天上课玩手机,下课玩电脑,吃饭叫外卖,从不去锻炼,周末就熬夜通宵,状态越来越差,导致我逐渐 ...
- Strust2: 工作流程
以下为Struts2的体系结构图: Struts2框架处理用户请求,大体分为以下几个过程: (1)用户发出一个HttpServletRequest请求 (2)请求经过一系列过滤器,最后达到Filter ...