题目链接:D Persistent Bookcase

题意:有一个n*m的书架,开始是空的,现在有k种操作:

1 x y 这个位置如果没书,放书。

2 x y 这个位置如果有书,拿走。

3 x 反转这一行,即有书的位置拿走,没书的位置放上书。

4 x 返回到第x步操作之后的书架。

现在给出q个操作,询问每次操作之后书架上书的数量。

思路:

开始没有思路。后来被告知dfs。

【词不达意。参考:http://blog.csdn.net/zyjhtutu/article/details/52279494】

对于第i次操作的后的书架,要么是由第i-1次操作后的书架得到的,要么是返回到第x步。而,每一步得到的书架书的数量只有一种可能。

将操作看成边,当前的状态看作节点,建树。建树的规则是,如果进行的操作树1或者2或者3,那么就将操作后状态连接在当前状态后面

,如果操作是4,就将操作后的状态连接在要还原的状态后面。然后进行dfs,离线求解。dfs的巧妙之处在于,由于数据量比较大,不可

能将每次操作后的状态都记下来。其实,仔细想想,根本不需要记录所有的状态,只需要记录当前状态,然后dfs,回溯的时候将更改的

状态在改回来。这样,一边dfs就解决问题。时间复杂度为q*m。

附代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <iostream>
  4. #include <vector>
  5. #define maxn 100100
  6. using namespace std;
  7.  
  8. vector<int> nxt[maxn];
  9. int ans[maxn];
  10. int op[maxn], r[maxn], c[maxn];
  11. bool vis[1010][1010]; //标记当前状态是否已经有书
  12. int n, m;
  13.  
  14. void init() {
  15. ans[0] = 0;
  16. for (int i=1; i<=maxn; ++i) {
  17. nxt[i].clear();
  18. }
  19. memset(vis, 0, sizeof(vis));
  20. }
  21.  
  22. void dfs(int x) {
  23. for (int i=0; i<nxt[x].size(); ++i) {
  24. int nxts = nxt[x][i]; // 从x出发能到达的所有状态
  25. //cout << nxts << " " << op[nxts] << "...\n";
  26. if (op[nxts] == 1) {
  27. if (vis[r[nxts]][c[nxts]]) { // 已经有书
  28. ans[nxts] = ans[x];
  29. dfs(nxts);
  30. }
  31. else {
  32. vis[r[nxts]][c[nxts]] = 1;
  33. ans[nxts] = ans[x] + 1;
  34. dfs(nxts);
  35. vis[r[nxts]][c[nxts]] = 0;
  36. }
  37. }
  38. else if (op[nxts] == 2) {
  39. if (vis[r[nxts]][c[nxts]] == 0) { // 没书
  40. ans[nxts] = ans[x];
  41. dfs(nxts);
  42. }
  43. else {
  44. vis[r[nxts]][c[nxts]] = 0;
  45. ans[nxts] = ans[x] - 1;
  46. dfs(nxts);
  47. vis[r[nxts]][c[nxts]] = 1;
  48. }
  49. }
  50. else if (op[nxts] == 3) {
  51. int cnt = 0;
  52. for (int j=1; j<=m; ++j) {
  53. if (vis[r[nxts]][j] == 0) {
  54. cnt++;
  55. vis[r[nxts]][j] = 1;
  56. }
  57. else {
  58. cnt--;
  59. vis[r[nxts]][j] = 0;
  60. }
  61. }
  62. ans[nxts] = ans[x] + cnt;
  63. dfs(nxts);
  64. for (int j=1; j<=m; ++j) {
  65. if (vis[r[nxts]][j] == 0) {
  66. vis[r[nxts]][j] = 1;
  67. }
  68. else vis[r[nxts]][j] = 0;
  69. }
  70. }
  71. else if (op[nxts] == 4) {
  72. ans[nxts] = ans[x];
  73. dfs(nxts);
  74. }
  75. }
  76. }
  77.  
  78. int main() {
  79. // freopen("in.cpp", "r", stdin);
  80. int q;
  81. while(~scanf("%d%d%d", &n, &m, &q)) {
  82. init();
  83. for (int i=1; i<=q; ++i) {
  84. scanf("%d", &op[i]);
  85. if (op[i] == 1 || op[i] == 2) {
  86. scanf("%d%d", &r[i], &c[i]);
  87. nxt[i-1].push_back(i);
  88. }
  89. else if (op[i] == 3) {
  90. scanf("%d", &r[i]);
  91. nxt[i-1].push_back(i);
  92. }
  93. else if (op[i] == 4) {
  94. scanf("%d", &r[i]);
  95. nxt[r[i]].push_back(i);
  96. }
  97. }
  98.  
  99. dfs(0);
  100. for (int i=1; i<=q; ++i) {
  101. printf("%d\n", ans[i]);
  102. }
  103. }
  104. return 0;
  105. }

确实很巧妙。

CodeForces #368 div2 D Persistent Bookcase DFS的更多相关文章

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

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

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

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

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

    题目链接:http://codeforces.com/contest/707/my 看了这位大神的详细分析,一下子明白了.链接:http://blog.csdn.net/queuelovestack/ ...

  4. CodeForces #369 div2 D Directed Roads DFS

    题目链接:D Directed Roads 题意:给出n个点和n条边,n条边一定都是从1~n点出发的有向边.这个图被认为是有环的,现在问你有多少个边的set,满足对这个set里的所有边恰好反转一次(方 ...

  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 Round #368 (Div. 2) D. Persistent Bookcase 离线 暴力

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

  7. Persistent Bookcase CodeForces - 707D (dfs 离线处理有根树模型的问题&&Bitset)

    Persistent Bookcase CodeForces - 707D time limit per test 2 seconds memory limit per test 512 megaby ...

  8. 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 ...

  9. CF #368 div2

    题目链接:http://codeforces.com/contest/707/problem/A A. Brain's Photos time limit per test 2 seconds mem ...

随机推荐

  1. window 下 xampp 上 安装memcached

    1.下载memcache 的window 稳定版,解压到xampp 目下;比如D:\xampp\memcached 2. 打开cmd 命令界面 输入 D:\xampp\memcached\ memca ...

  2. js 倒计时(可自定义时间)

    <html> <head> <title>js 倒计时</title> </head> <body> <div> & ...

  3. React Native for Android 学习笔记

    C:\Users\Vic Lee\AwesomeProject>react-native run-android Starting JS server... Running D:\Android ...

  4. 外媒速递:十大最佳心理学概念助你提升Web设计效果

    外媒速递是核子可乐精选的近日国外媒体的精彩文章推荐,希望大家喜欢! 本期给大家推荐的是帮助你提升Web设计效果的十大最佳心理学概念.改善企业云环境协作效率的九款卓越工具.选择移动应用开发工具时要考虑的 ...

  5. 续并查集学习笔记——Gang团伙题解

    一言不合先贴题目 Description 在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1. 我朋友的朋友是我的朋友: 2. 我敌人的敌人是我的朋友: 所有是朋友的人组成一个团伙 ...

  6. Xcode8.0 去除控制台多余打印

    选择Product->Scheme->Edit Scheme ...或者直接按 command + shift + < 快捷键,在弹出的窗口中Environment Variable ...

  7. Qt设计师学习笔记--Sharping-Changing Dialogs

    1.pushbutton->default属性为true,按回车相当于点击该按钮. 2.选中checkable后,Button变成切换按钮(toggle button),可以有两种状态:按下/弹 ...

  8. Java类的加载

    1.类的加载步骤 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载.连接.初始化三步来实现对这个类的初始化 加载:将class文件读入内存,并为之创建一个Class对象,任何类被使用 ...

  9. 相机位姿估计0:基本原理之如何解PNP问题

    关键词:相机位姿估计 PNP问题求解 用途:各种位姿估计 文章类型:原理 @Author:VShawn(singlex@foxmail.com) @Date:2016-11-18 @Lab: CvLa ...

  10. js 对多sheet Excel赋值操作

    function ExpExcel(){ var tempStr = ""; var filePath ="" var excelname=ReportFile ...