CodeForces 707D Persistent Bookcase ——(巧妙的dfs)

  一个n*m的矩阵,有四种操作:

  1.(i,j)处变1;

  2.(i,j)处变0;

  3.第i行的所有位置1,0反转;

  4.回到第k次操作以后的状态;

  问每次操作以后整个矩阵里面有多少个1。

  其实不好处理的操作只有第四个,但是这题的思路很巧妙,123三种操作全部建立顺边,第四种操作将k和这次操作的序号建边,然后dfs进行操作即可,遇到尽头,则退回到前一个分岔点,并且回溯的过程中将操作反转。

  具体见代码:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <vector>
 5 using namespace std;
 6 const int N = 100000 + 5;
 7
 8 int n,m,q,op[N],x[N],y[N],a[1000+5][1000+5];
 9 vector<int> G[N];
10 int cnt = 0,ans[N];
11
12 void dfs(int u)
13 {
14     bool have_changed = 0;
15     if(op[u]==1 && a[x[u]][y[u]]==0) {have_changed = true;a[x[u]][y[u]] = 1;cnt++;}
16     if(op[u]==2 && a[x[u]][y[u]]==1) {have_changed = true;a[x[u]][y[u]] = 0;cnt--;}
17     if(op[u]==3)
18     {
19         have_changed = true;
20         for(int i=1;i<=m;i++)
21         {
22             if(a[x[u]][i] == 1) {cnt--;a[x[u]][i] = 0;}
23             else {cnt++;a[x[u]][i] = 1;}
24         }
25     }
26     ans[u] = cnt;
27     for(int i=0;i<G[u].size();i++) dfs(G[u][i]);
28     if(!have_changed) return;
29     if(op[u]==1) {a[x[u]][y[u]] = 0;cnt--;}
30     if(op[u]==2) {a[x[u]][y[u]] = 1;cnt++;}
31     if(op[u]==3)
32     {
33         for(int i=1;i<=m;i++)
34         {
35             if(a[x[u]][i] == 1) {cnt--;a[x[u]][i] = 0;}
36             else {cnt++;a[x[u]][i] = 1;}
37         }
38     }
39 }
40
41 int main()
42 {
43     scanf("%d%d%d",&n,&m,&q);
44     for(int i=1;i<=q;i++)
45     {
46         scanf("%d",op+i);
47         if(op[i]<=2) scanf("%d%d",x+i,y+i);
48         else scanf("%d",x+i);
49         if(op[i] == 4) G[x[i]].push_back(i);
50         else G[i-1].push_back(i);
51     }
52     for(int i=0;i<G[0].size();i++) dfs(G[0][i]);
53     for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
54 }
时间: 2024-10-20 11:41:37

CodeForces 707D Persistent Bookcase ——(巧妙的dfs)的相关文章

【深搜】【数】Codeforces 707D Persistent Bookcase

题目链接: http://codeforces.com/problemset/problem/707/D 题目大意: 一个N*M的书架,支持4种操作 1.把(x,y)变为有书. 2.把(x,y)变为没书. 3.把x行上的所有书状态改变,有变没,没变有. 4.回到第K个操作时的状态. 求每一次操作后书架上总共多少书. 题目思路: [深搜][树] 现场有一点思路不过没敢写哈.还是太弱了. 总共只用保存一张图,把操作看成一棵树,一开始I操作连接在I-1操作后,如果遇到操作4的话,把I操作与I-1操作的

CodeForces 707D Persistent Bookcase

$dfs$,优化. $return$操作说明该操作完成之后的状态和经过操作$k$之后的状态是一样的.因此我们可以建树,然后从根节点开始$dfs$一次(回溯的时候复原一下状态)就可以算出所有状态的答案. 对于$1$和$2$操作,可以开一个数组$a[i][j]$记录每一格子被操作$1$和$2$操作了几次. 然后开一个数组$r[i]$记录每一行被操作$3$操作了几次. 每一个真正的状态为$\left( {a\left[ i \right]\left[ j \right] + r\left[ i \ri

cf707D. Persistent Bookcase(离线+dfs)

题目链接:http://codeforces.com/problemset/problem/707/D  有一个n*m的书架,有K个操作,求每个操作后一共有多少本书:有4种操作: 1:x y 如果 x y 位置没有书,放一本书在上面: 2:x y如果 x y 位置有书,移走: 3:x,表示把第x行的所有又书的拿走,没书的放上去: 4:k,回到第k个操作后的状态: 离线处理k个操作:当操作不为 4 时,把操作i连在i-1后,=4时把操作 i 连在a[i].x后: 这样建一棵树,然后遍历即可,在回溯

CodeForces #368 div2 D Persistent Bookcase DFS

题目链接: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/5227949

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

D. Persistent Bookcase 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

Codeforces 6D Lizards and Basements 2 dfs+暴力

题目链接:点击打开链接 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h> #include<queue> #include<string> #include<stdlib.h> #include<a

CodeForces 440C One-Based Arithmetic(递归,dfs)

A - One-Based Arithmetic Time Limit:500MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-08-21) Description Prof. Vasechkin wants to represent positive integer n as a sum of adden

Codeforces 455C Civilization(并查集+dfs)

题目链接:Codeforces 455C Civilization 题目大意:给定N,M和Q,N表示有N个城市,M条已经修好的路,修好的路是不能改变的,然后是Q次操作,操作分为两种,一种是查询城市x所在的联通集合中,最长的路为多长.二是连接两个联通集合,采用联通之后最长路最短的方案. 解题思路:因为一开时的图是不可以改变的,所以一开始用dfs处理出各个联通集合,并且记录住最大值,然后就是Q次操作,用并查集维护,注意因为联通的时候要采用最长路径最短的方案,所以s的转移方程变为s = max(s,

codeforces 707D:Persistent Bookcase

Description 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