Persistent Bookcase

题目链接http://codeforces.com/contest/707/problem/D

注释:略。


题解

发现虽然$q\le 10^5$但是网格是$1000\times 1000$的,而且每次操作只会操作一行。

故此我们考虑按照行来搞。

想到每次暴力重新建一行,但是空间开不下,我们用$bitset$即可。

但是我们又面临一个问题,即:回到某一个时刻。

这个很难弄,最简单的支持可持久化的数据结构是主席树,所以我们对行建主席树。

每次修改操作我们都新开一个$bitset$,主席树的第$i$个叶子表示的是第$i$行对应哪一个$bitset$。

时间复杂度为$O(\frac{np}{32} +plogn)$。

代码

#include <bits/stdc++.h>

#define setIO(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout) 

#define N 400010 

using namespace std;

bitset <1010 > b[N], mdl;

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
int x = 0, f = 1;
char c = nc();
while (c < 48) {
if (c == '-')
f = -1;
c = nc();
}
while (c > 47) {
x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
}
return x * f;
} int cnt = 0, rt[N]; struct Node {
int v;
int ls, rs;
}a[N * 30]; void update(int x, int val, int l, int r, int &p, int pre) {
p = ++cnt;
a[p] = a[pre];
if (l == r) {
a[p].v = val;
return;
}
int mid = (l + r) >> 1;
if (x <= mid) {
update(x, val, l, mid, a[p].ls, a[pre].ls);
}
else {
update(x, val, mid + 1, r, a[p].rs, a[pre].rs);
}
} int query(int x, int l, int r, int p) {
if (l == r) {
return a[p].v;
}
int mid = (l + r) >> 1;
if (x <= mid) {
return query(x, l, mid, a[p].ls);
}
else {
return query(x, mid + 1, r, a[p].rs);
}
} int ans[N]; void build(int l, int r, int &p) {
if (!p) {
p = ++cnt;
}
if (l == r) {
a[p].v = l;
return;
}
int mid = (l + r) >> 1;
build(l, mid, a[p].ls), build(mid + 1, r, a[p].rs);
} int main() {
// setIO("now");
int n = rd(), m = rd(), q = rd();
for (int i = 1; i <= m; i ++ ) {
// 1 << (i - 1)
mdl.set(i);
}
build(1, n, rt[0]);
int tmp = n;
for (int i = 1; i <= q; i ++ ) {
int opt = rd();
ans[i] = ans[i - 1];
if (opt == 1) {
int x = rd(), y = rd();
int z = query(x, 1, n, rt[i - 1]);
b[ ++ tmp] = b[z];
b[tmp].set(y);
ans[i] += b[tmp].count() - b[z].count();
update(x, tmp, 1, n, rt[i], rt[i - 1]);
}
else if (opt == 2) {
int x = rd(), y = rd();
int z = query(x, 1, n, rt[i - 1]);
b[ ++ tmp] = b[z];
b[tmp].reset(y);
ans[i] += b[tmp].count() - b[z].count();
update(x, tmp, 1, n, rt[i], rt[i - 1]);
}
else if (opt == 3) {
int x = rd();
int z = query(x, 1, n, rt[i - 1]);
b[ ++ tmp] = b[z];
b[tmp].flip();
b[tmp] = b[tmp] & mdl;
ans[i] += b[tmp].count() - b[z].count();
update(x, tmp, 1, n, rt[i], rt[i - 1]);
}
else {
int x = rd();
ans[i] = ans[x];
rt[i] = rt[x];
}
printf("%d\n", ans[i]);
}
return 0;
}

[CF707D]Persistent Bookcase_主席树_bitset的更多相关文章

  1. POJ 2104 K-th Number(主席树——附讲解)

    Description You are working for Macrohard company in data structures department. After failing your ...

  2. BZOJ.3489.A simple rmq problem(主席树 Heap)

    题目链接 当时没用markdown写,可能看起来比较难受...可以复制到别的地方看比如DevC++. \(Description\) 给定一个长为n的序列,多次询问[l,r]中最大的只出现一次的数.强 ...

  3. HDU2665Kth number (主席树+离散)

    Give you a sequence and ask you the kth big number of a inteval. InputThe first line is the number o ...

  4. 静态区间第k大(主席树)

    POJ 2104为例(主席树入门题) 思想: 可持久化线段树,也叫作函数式线段树,也叫主席树(高大上). 可持久化数据结构(Persistent data structure):利用函数式编程的思想使 ...

  5. CF707D Persistent Bookcase

    CF707D Persistent Bookcase 洛谷评测传送门 题目描述 Recently in school Alina has learned what are the persistent ...

  6. bzoj3207--Hash+主席树

    题目大意: 给定一个n个数的序列和m个询问(n,m<=100000)和k,每个询问包含k+2个数字:l,r,b[1],b[2]...b[k],要求输出b[1]~b[k]在[l,r]中是否出现. ...

  7. bzoj1901--树状数组套主席树

    树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...

  8. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  9. BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]

    1146: [CTSC2008]网络管理Network Time Limit: 50 Sec  Memory Limit: 162 MBSubmit: 3522  Solved: 1041[Submi ...

随机推荐

  1. [git]一个本地仓库,多个远程仓库

    操作步骤如下: 1. 克隆某个远程仓库的代码到本地 git clone http://...... // 或者 git clone git@.... 2. 查看当前远程仓库地址 // 查看需要添加的远 ...

  2. 为什么说Redis是单线程的?

    一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”.什么是“热数据和冷数据” ,复杂一点的会问到缓存雪崩.缓存穿透.缓存预热.缓存更新.缓存降级等问题,这些看 ...

  3. id/su/chage/cash

    id 查看用户的uid,gid及归属的用户组 chage 修改用户密码有效期限

  4. [2]windows内核情景分析--系统调用

    Windows的地址空间分用户模式与内核模式,低2GB的部分叫用户模式,高2G的部分叫内核模式,位于用户空间的代码不能访问内核空间,位于内核空间的代码却可以访问用户空间 一个线程的运行状态分内核态与用 ...

  5. 区间DP小结 及例题分析:P1880 [NOI1995]石子合并,P1063 能量项链

    区间类动态规划 一.基本概念 区间类动态规划是线性动态规划的拓展,它在分阶段划分问题时,与阶段中元素出现的顺序和由前一阶段的那些元素合并而来由很大的关系.例如状态f [ i ][ j ],它表示以已合 ...

  6. java spring boot- freemarker 配置 yml使用流程

    1.pom.xml  加入maven 依赖 <!-- 引入 freemarker 模板依赖 --><dependency> <groupId>org.springf ...

  7. keepalived+mysql双主热备

    这里使用keepalived实现mysql的双主热备高可用 实验环境: 主机名 IP 系统版本 软件版本 master 192.168.199.6/vip:192.168.199.111 Rhel7. ...

  8. PyTricks-How to Sort a Python dict

    字典的键值排序 import operator # 1表示按照值排序 xs = {"a": 4, "b": 3, "c": 2, " ...

  9. CTF辅助脚本

    首先推荐这篇文章,网上有多次转载,这是我见过日期比较早的 CTF中那些脑洞大开的编码和加密 凯撒密码 flag='flag{abcdef}' c='' n=20 for i in flag: if ' ...

  10. 如何用CSS3来实现卡片的翻转特效

    CSS3实现翻转(Flip)效果 动画效果 效果分析 当鼠标滑过包含块时,元素整体翻转180度,以实现“正”“反”面的切换. HTML分析 分析:.container,.flip为了实现动画效果做准备 ...