Persistent Bookcase

CodeForces - 707D

time limit per test 2 seconds

memory limit per test 512 megabytes

input

standard input

output

standard output

Recently in school Alina has learned what are the persistent data structures: they are data structures that always preserves the previous version of itself and access to it when it is modified.

After reaching home Alina decided to invent her own persistent data structure. Inventing didn't take long: there is a bookcase right behind her bed. Alina thinks that the bookcase is a good choice for a persistent data structure. Initially the bookcase is empty, thus there is no book at any position at any shelf.

The bookcase consists of n shelves, and each shelf has exactly m positions for books at it. Alina enumerates shelves by integers from 1 to n and positions at shelves — from 1 to m. Initially the bookcase is empty, thus there is no book at any position at any shelf in it.

Alina wrote down q operations, which will be consecutively applied to the bookcase. Each of the operations has one of four types:

  • 1 i j — Place a book at position j at shelf i if there is no book at it.
  • 2 i j — Remove the book from position j at shelf i if there is a book at it.
  • 3 i — Invert book placing at shelf i. This means that from every position at shelf i which has a book at it, the book should be removed, and at every position at shelf i which has not book at it, a book should be placed.
  • 4 k — Return the books in the bookcase in a state they were after applying k-th operation. In particular, k = 0 means that the bookcase should be in initial state, thus every book in the bookcase should be removed from its position.

After applying each of operation Alina is interested in the number of books in the bookcase. Alina got 'A' in the school and had no problem finding this values. Will you do so?

Input

The first line of the input contains three integers n, m and q (1 ≤ n, m ≤ 103, 1 ≤ q ≤ 105) — the bookcase dimensions and the number of operations respectively.

The next q lines describes operations in chronological order — i-th of them describes i-th operation in one of the four formats described in the statement.

It is guaranteed that shelf indices and position indices are correct, and in each of fourth-type operation the number k corresponds to some operation before it or equals to 0.

Output

For each operation, print the number of books in the bookcase after applying it in a separate line. The answers should be printed in chronological order.

Examples

input

Copy

  1. 2 3 31 1 13 24 0

output

Copy

  1. 140

input

Copy

  1. 4 2 63 22 2 23 33 22 2 23 2

output

Copy

  1. 213324

input

Copy

  1. 2 2 23 22 2 1

output

Copy

  1. 21

Note

This image illustrates the second sample case.

题意:

​ 现在有一个N*M的书架,有Q个操作,对于每个操作,输入opt:

​ 如果opt==1,那么输入x,y,如果第x行第y列无书,则放一本书。

​ 如果opt==2,那么输入x,y,如果第x行第y列有书,则取走那本书。

​ 如果opt==3,那么输入x,将第x行有书的取走,无书的位置放一本。

​ 如果opt==4,那么输入k,表示把书架的情况恢复为第k次操作后的样貌,k在当前操作之前。

思路:

注意到整体操作顺序为有根树,可以DFS回溯处理,对于书架上的书个数情况,可以直接用bitset。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <bits/stdc++.h>
  5. #include <cmath>
  6. #include <queue>
  7. #include <stack>
  8. #include <map>
  9. #include <set>
  10. #include <vector>
  11. #include <iomanip>
  12. #define ALL(x) (x).begin(), (x).end()
  13. #define sz(a) int(a.size())
  14. #define rep(i,x,n) for(int i=x;i<n;i++)
  15. #define repd(i,x,n) for(int i=x;i<=n;i++)
  16. #define pii pair<int,int>
  17. #define pll pair<long long ,long long>
  18. #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
  19. #define MS0(X) memset((X), 0, sizeof((X)))
  20. #define MSC0(X) memset((X), '\0', sizeof((X)))
  21. #define pb push_back
  22. #define mp make_pair
  23. #define fi first
  24. #define se second
  25. #define eps 1e-6
  26. #define gg(x) getInt(&x)
  27. #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
  28. #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
  29. #define du2(a,b) scanf("%d %d",&(a),&(b))
  30. #define du1(a) scanf("%d",&(a));
  31. using namespace std;
  32. typedef long long ll;
  33. ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
  34. ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
  35. ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
  36. void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
  37. void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
  38. inline void getInt(int *p);
  39. const int maxn = 1010;
  40. const int manq = 1e5 + 10;
  41. const int inf = 0x3f3f3f3f;
  42. /*** TEMPLATE CODE * * STARTS HERE ***/
  43. bitset<maxn> a[maxn], p;
  44. int n, m;
  45. int q;
  46. int op[manq];
  47. int x[manq];
  48. int y[manq];
  49. std::vector<int> son[manq];
  50. int ans[manq];
  51. void dfs(int u, int now)
  52. {
  53. for (auto v : son[u]) {
  54. if (op[v] == 1) {
  55. if (a[x[v]][y[v]] == 0) {
  56. a[x[v]][y[v]] = 1;
  57. ans[v] = now + 1;
  58. dfs(v, now + 1);
  59. a[x[v]][y[v]] = 0;
  60. } else {
  61. ans[v] = now ;
  62. dfs(v, now );
  63. }
  64. } else if (op[v] == 2) {
  65. if (a[x[v]][y[v]] == 1) {
  66. a[x[v]][y[v]] = 0;
  67. ans[v] = now - 1;
  68. dfs(v, now - 1);
  69. a[x[v]][y[v]] = 1;
  70. } else {
  71. ans[v] = now ;
  72. dfs(v, now );
  73. }
  74. } else if (op[v] == 3) {
  75. ans[v] = now - a[x[v]].count();
  76. a[x[v]] ^= p;
  77. ans[v] += a[x[v]].count();
  78. dfs(v, ans[v]);
  79. a[x[v]] ^= p;
  80. } else if (op[v] == 4) {
  81. ans[v] = ans[x[v]];
  82. dfs(v, ans[v]);
  83. }
  84. }
  85. }
  86. int main()
  87. {
  88. //freopen("D:\\code\\text\\input.txt","r",stdin);
  89. //freopen("D:\\code\\text\\output.txt","w",stdout);
  90. du3(n, m, q);
  91. repd(i, 1, m) {
  92. p.set(i);
  93. }
  94. repd(i, 1, q) {
  95. du1(op[i]);
  96. if (op[i] <= 2) {
  97. du2(x[i], y[i]);
  98. } else {
  99. du1(x[i]);
  100. }
  101. if (op[i] <= 3) {
  102. son[i - 1].push_back(i);
  103. } else {
  104. son[x[i]].push_back(i);
  105. }
  106. }
  107. dfs(0, 0);
  108. repd(i, 1, q) {
  109. printf("%d\n", ans[i]);
  110. }
  111. return 0;
  112. }
  113. inline void getInt(int *p)
  114. {
  115. char ch;
  116. do {
  117. ch = getchar();
  118. } while (ch == ' ' || ch == '\n');
  119. if (ch == '-') {
  120. *p = -(getchar() - '0');
  121. while ((ch = getchar()) >= '0' && ch <= '9') {
  122. *p = *p * 10 - ch + '0';
  123. }
  124. } else {
  125. *p = ch - '0';
  126. while ((ch = getchar()) >= '0' && ch <= '9') {
  127. *p = *p * 10 + ch - '0';
  128. }
  129. }
  130. }

Persistent Bookcase CodeForces - 707D (dfs 离线处理有根树模型的问题&&Bitset)的更多相关文章

  1. D. Persistent Bookcase(Codeforces Round #368 (Div. 2))

    D. Persistent Bookcase time limit per test 2 seconds memory limit per test 512 megabytes input stand ...

  2. codeforces 707D D. Persistent Bookcase(dfs)

    题目链接: D. Persistent Bookcase time limit per test 2 seconds memory limit per test 512 megabytes input ...

  3. CodeForces #368 div2 D Persistent Bookcase DFS

    题目链接:D Persistent Bookcase 题意:有一个n*m的书架,开始是空的,现在有k种操作: 1 x y 这个位置如果没书,放书. 2 x y 这个位置如果有书,拿走. 3 x 反转这 ...

  4. Codeforces Round #368 (Div. 2) D. Persistent Bookcase 离线 暴力

    D. Persistent Bookcase 题目连接: http://www.codeforces.com/contest/707/problem/D Description Recently in ...

  5. Codeforces Round #368 (Div. 2) D. Persistent Bookcase

    Persistent Bookcase Problem Description: Recently in school Alina has learned what are the persisten ...

  6. 【Codeforces-707D】Persistent Bookcase DFS + 线段树

    D. Persistent Bookcase Recently in school Alina has learned what are the persistent data structures: ...

  7. CF707D Persistent Bookcase

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

  8. Persistent Bookcase

    Persistent Bookcase time limit per test 2 seconds memory limit per test 512 megabytes input standard ...

  9. CodeForces 877E DFS序+线段树

    CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...

随机推荐

  1. Linux系统管理----LVM逻辑卷和磁盘配额作业习题

    1.为主机增加80G SCSI 接口硬盘 2.划分三个各20G的主分区 [root@localhost chen]# fdisk /dev/sdb 命令(输入 m 获取帮助):n Partition ...

  2. gdb调试工具学习

    GDB 是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但如果你是在 UNIX平台下做软件,你会发现GDB这个调试工具有比 ...

  3. 洛谷 题解 P1220 【关路灯 】

    搜索 传参 inline void DFS(int now,int l,int r,int cnt,int sum,int k) /* now为当前点 l为左端点 r为右端点 cnt为当前耗电量 su ...

  4. [转帖]GNU/Linux与开源文化的那些人和事

    GNU/Linux与开源文化的那些人和事 时间:2015-09-24   作者:admin 分类:新手入门 阅读:167次 http://embeddedlinux.org.cn/emb-linux/ ...

  5. Ajax的使用及后台如何传参

    Ajax的使用(此处为表单序列化方式) $.ajax({ type: 'post', data: $('#newPriorityForm').serialize(), dataType: 'json' ...

  6. 记2017年年底,几次Python后端面试

    1. 果壳 电话面试: 说一下TCP的三次握手,四次挥手,为什么会这样? http安全的性的了解,说一下对cookie和session的了解: 对mysql的了解,说一下你常用的数据类型,char和v ...

  7. Spark的lazy特性有什么意义呢?

    [学习笔记] Spark通过lazy特性有什么意义呢? Spark通过lazy特性,可以进行底层的spark应用执行的优化.在生活中,就像三思而后行.谋定而后动. 文章转载自原文:https://bl ...

  8. H5网页唤醒app,判断app安装

    在阅读本文之前你首先应该对js有基本对掌握,并且对Scheme,intent有一定的理解.更多的是代码 上午给朋友做了一个产品引导页,但是需要判断ios系统的TestFlight是否安装,进行了goo ...

  9. 字典的setdefault()

    setdefault(key, default) 函数 ---有key获取值.没key设置 key:default dict.setdefault(key, default=None) 如果 key ...

  10. 一个MySQL JDBC驱动bug引起的血案

    1.1      问题背景 公司是做电商系统的,整个系统搭建在华为云上.系统设计的时候,考虑到后续的用户和订单数量比较大,需要使用一些大数据库的组件.关系型数据库这块,考虑到后续数据量的快速增长,不是 ...