CodeForces #368 div2 D Persistent Bookcase DFS
题意:有一个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。
附代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>
#define maxn 100100
using namespace std; vector<int> nxt[maxn];
int ans[maxn];
int op[maxn], r[maxn], c[maxn];
bool vis[1010][1010]; //标记当前状态是否已经有书
int n, m; void init() {
ans[0] = 0;
for (int i=1; i<=maxn; ++i) {
nxt[i].clear();
}
memset(vis, 0, sizeof(vis));
} void dfs(int x) {
for (int i=0; i<nxt[x].size(); ++i) {
int nxts = nxt[x][i]; // 从x出发能到达的所有状态
//cout << nxts << " " << op[nxts] << "...\n";
if (op[nxts] == 1) {
if (vis[r[nxts]][c[nxts]]) { // 已经有书
ans[nxts] = ans[x];
dfs(nxts);
}
else {
vis[r[nxts]][c[nxts]] = 1;
ans[nxts] = ans[x] + 1;
dfs(nxts);
vis[r[nxts]][c[nxts]] = 0;
}
}
else if (op[nxts] == 2) {
if (vis[r[nxts]][c[nxts]] == 0) { // 没书
ans[nxts] = ans[x];
dfs(nxts);
}
else {
vis[r[nxts]][c[nxts]] = 0;
ans[nxts] = ans[x] - 1;
dfs(nxts);
vis[r[nxts]][c[nxts]] = 1;
}
}
else if (op[nxts] == 3) {
int cnt = 0;
for (int j=1; j<=m; ++j) {
if (vis[r[nxts]][j] == 0) {
cnt++;
vis[r[nxts]][j] = 1;
}
else {
cnt--;
vis[r[nxts]][j] = 0;
}
}
ans[nxts] = ans[x] + cnt;
dfs(nxts);
for (int j=1; j<=m; ++j) {
if (vis[r[nxts]][j] == 0) {
vis[r[nxts]][j] = 1;
}
else vis[r[nxts]][j] = 0;
}
}
else if (op[nxts] == 4) {
ans[nxts] = ans[x];
dfs(nxts);
}
}
} int main() {
// freopen("in.cpp", "r", stdin);
int q;
while(~scanf("%d%d%d", &n, &m, &q)) {
init();
for (int i=1; i<=q; ++i) {
scanf("%d", &op[i]);
if (op[i] == 1 || op[i] == 2) {
scanf("%d%d", &r[i], &c[i]);
nxt[i-1].push_back(i);
}
else if (op[i] == 3) {
scanf("%d", &r[i]);
nxt[i-1].push_back(i);
}
else if (op[i] == 4) {
scanf("%d", &r[i]);
nxt[r[i]].push_back(i);
}
} dfs(0);
for (int i=1; i<=q; ++i) {
printf("%d\n", ans[i]);
}
}
return 0;
}
确实很巧妙。
CodeForces #368 div2 D Persistent Bookcase DFS的更多相关文章
- codeforces 707D D. Persistent Bookcase(dfs)
题目链接: D. Persistent Bookcase time limit per test 2 seconds memory limit per test 512 megabytes input ...
- 【Codeforces-707D】Persistent Bookcase DFS + 线段树
D. Persistent Bookcase Recently in school Alina has learned what are the persistent data structures: ...
- Codeforces Round #368 (Div. 2)D. Persistent Bookcase DFS
题目链接:http://codeforces.com/contest/707/my 看了这位大神的详细分析,一下子明白了.链接:http://blog.csdn.net/queuelovestack/ ...
- CodeForces #369 div2 D Directed Roads DFS
题目链接:D Directed Roads 题意:给出n个点和n条边,n条边一定都是从1~n点出发的有向边.这个图被认为是有环的,现在问你有多少个边的set,满足对这个set里的所有边恰好反转一次(方 ...
- Codeforces Round #368 (Div. 2) D. Persistent Bookcase
Persistent Bookcase Problem Description: Recently in school Alina has learned what are the persisten ...
- Codeforces Round #368 (Div. 2) D. Persistent Bookcase 离线 暴力
D. Persistent Bookcase 题目连接: http://www.codeforces.com/contest/707/problem/D Description Recently in ...
- Persistent Bookcase CodeForces - 707D (dfs 离线处理有根树模型的问题&&Bitset)
Persistent Bookcase CodeForces - 707D time limit per test 2 seconds memory limit per test 512 megaby ...
- 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 ...
- CF #368 div2
题目链接:http://codeforces.com/contest/707/problem/A A. Brain's Photos time limit per test 2 seconds mem ...
随机推荐
- css样式基础三
css的定位: 其中css中被分为块级元素与行内元素.如块级元素div.hx标签.p元素.行内元素span和strong W3school给出的一切皆为框的定义. 而且可以使用display属性,强行 ...
- linux解压/压缩文件
1.*.tar 用 tar –xvf 解压 2.*.gz 用 gzip -d或者gunzip 解压 3.*.tar.gz和*.tgz 用 tar –xzf 解压 4.*.bz2 用 bzip2 ...
- javascirpt对象运用与JS变量
abcdefghijklmnopqrstuvwyz String 对象方法 charAt() 方法可返回指定位置的字符.stringObject.charAt(index)(index从0开始)[ht ...
- idea jrebel6 安装,破解
一.Setting中在线安装JRebel插件,install 二.拷贝下载的jrebel.rar解压后 把里面内容覆盖IDEA插件安装目录中此插件目录之下 下载:http://pan.baidu.co ...
- JavaScript数组类型
特点 动态长度 一个数组里面的元素可以是不同类型 数组的length属性不是只读属性,可通过length延长数组也可以删减数组的长度 定义数组两种方法 //方法一: var names = new A ...
- [SAP ABAP开发技术总结]ABAP调优——Open SQL优化
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 浅谈一下关于使用css3来制作圆环进度条
最近PC端项目要做一个这样的页面出来,其他的都很简单,关键在于百分比的圆环效果.我最初打算是直接使用canvas来实现的,因为canvas实现一个圆是很简便的. 下面贴出canvas实现圆环的代码,有 ...
- 非标准JSON解析
http://blog.csdn.net/superit401/article/details/51734591 String category = "{'v-soft-list':[{ty ...
- cfDNA(circulating cell free DNA)全基因组测序
参考资料: [cfDNA专题]cell-free DNA在非肿瘤疾病中的临床价值(好) ctDNA, cfDNA和CTCs有什么区别吗? cfDNA你懂多少? 新发现 | 基因是否表达,做个cfDNA ...
- qq加好友加群限制ip怎么解决
目前各样格式的推广都会用到腾讯QQ,现在就遇到了问题.QQ加好友加群,经常会提示你的账号存在不安全因素,暂停加好友功能.这个原因都是本地同一个IP,登陆的QQ过多,加好友过多.导致这个IP被记录,相当 ...