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;
}

最新文章

  1. Dapper:The member of type SeoTKD cannot be used as a parameter Value
  2. GJM: 设计模式 - 模板方法模式(Template Method)
  3. Java语言的安全性的体现
  4. 中文版Windows Server 2012 R2更改为英文显示语言
  5. org.openqa.selenium.remote.SessionNotFoundException: The FirefoxDriver cannot be used after quit() was called.
  6. C#超时处理(转载)
  7. ##DAY4 事件的基本概念、触摸的基本概念、响应者链、手势
  8. input type=&quot;file&quot; 的一些问题
  9. poj 1654 Area(计算几何--叉积求多边形面积)
  10. JAVA版A星算法实现
  11. bzoj1015星球大战
  12. JavaScript中的单体模式四种实现方式
  13. UNIX环境高级编程——线程同步之互斥量
  14. NET Core 1.1中使用Jwt
  15. 百度杯 ctf 九月场---Text
  16. STL库学习笔记(待补充QAQ
  17. Ubuntu 停止 mydesktop 服务
  18. python基础下的数据结构与算法之链表
  19. 【转载】ArcEngine ITable 与System.DataTable相互转换
  20. django之创建第6-1个项目-自定义过滤器

热门文章

  1. About Grisha N. ( URAL - 2012 )
  2. lodop第三方插件的使用
  3. 1632:【 例 2】[NOIP2012]同余方程
  4. hive 调优(一)coding调优
  5. 手写alert弹框(一)
  6. Spring框架IOC解说
  7. puppeteer注入cookie然后访问页面
  8. 在windows平台下搭建Django项目虚拟环境
  9. MySQLUNION_连接两个以上的 SELECT 语句的结果组合到一个结果集合
  10. 文件上传对servlet的要求