Codeforces 747D Persistent Bookcase【Dfs+思维】好题!好题!
来源:互联网 发布:网络成熟男人经典语录 编辑:程序博客网 时间:2024/05/16 09:54
题目大意:
一共四种操作:
①1 x y 如果位子(x,y)没有书,就在上边放一本书。
②2 x y 如果位子(x,y)有书,就拿走这本书。
③ 3 x 在第x行上,如果有书,就拿走,如果没有书 ,就放一本。
④4 x 回到第x次操作结束后的状态。
问每个操作结束后,书架上共有多少本书。
思路(源自:http://blog.csdn.net/miracle_ma/article/details/52290831,很妙的解法):
1、首先我们优化修改操作,我们可以将第三种操作也变成O(1);
我们过程维护一个row【x】,表示第x行有多少本书,那么对应第三种操作对于总数量的影响为:sum=sum-row【x】+m-row【x】;
同时,对于书架的第x行,我们进行了一次翻转,那么维护一个数组fan【x】,记录第x行是否翻转过。
那么过程维护这个sum和几个数组还是很简单的。
三种操作配合亦或,总查询复杂度O(1);
2、再考虑到Dfs的特点,我们考虑用Dfs的方式来搞这个题。
首先,对于每个修改操作,对应将i-1和i连边.
如果不是修改操作(op==4),对应将回到的位子和i连边。
接下来维护Dfs过程即可。
Ac代码:
#include<stdio.h>#include<vector>#include<string.h>using namespace std;struct node{ int op,x,y;}p[100050];vector<int >mp[100005];int a[1005][1005];int fan[1005];int row[1005];int ans[100505];int n,m,q,sum;void Dfs(int pos){ int flag=0; if(pos!=0) { if(p[pos].op==1) { if(a[p[pos].x][p[pos].y]^fan[p[pos].x]==0) { sum++; a[p[pos].x][p[pos].y]^=1; row[p[pos].x]++; flag=1; } } if(p[pos].op==2) { if(a[p[pos].x][p[pos].y]^fan[p[pos].x]==1) { sum--; a[p[pos].x][p[pos].y]^=1; row[p[pos].x]--; flag=1; } } if(p[pos].op==3) { sum-=row[p[pos].x]; sum+=m-row[p[pos].x]; fan[p[pos].x]^=1; row[p[pos].x]=m-row[p[pos].x]; flag=1; } ans[pos]=sum; } for(int i=0;i<mp[pos].size();i++) { int v=mp[pos][i]; Dfs(v); } if(pos!=0&&flag==1) { if(p[pos].op==1) { sum--; a[p[pos].x][p[pos].y]^=1; row[p[pos].x]--; } if(p[pos].op==2) { sum++; a[p[pos].x][p[pos].y]^=1; row[p[pos].x]++; flag=1; } if(p[pos].op==3) { sum-=row[p[pos].x]; sum+=m-row[p[pos].x]; fan[p[pos].x]^=1; row[p[pos].x]=m-row[p[pos].x]; flag=1; } }}int main(){ while(~scanf("%d%d%d",&n,&m,&q)) { for(int i=1;i<=100003;i++)mp[i].clear(); for(int i=1;i<=q;i++) { scanf("%d",&p[i].op); if(p[i].op==1||p[i].op==2)scanf("%d%d",&p[i].x,&p[i].y); else scanf("%d",&p[i].x); if(p[i].op==4) { mp[p[i].x].push_back(i); } else { mp[i-1].push_back(i); } } sum=0; memset(a,0,sizeof(a)); memset(fan,0,sizeof(fan)); memset(row,0,sizeof(row)); memset(ans,0,sizeof(ans)); Dfs(0); for(int i=1;i<=q;i++) { printf("%d\n",ans[i]); } }}
0 0
- Codeforces 747D Persistent Bookcase【Dfs+思维】好题!好题!
- Codeforces 707D.Persistent Bookcase(离线算法,dfs树,好题!)
- Codeforces 707D Persistent Bookcase(DFS)
- Codeforces Problem 707D Persistent Bookcase(dfs+bitset)
- Codeforces 707D Persistent Bookcase(bitset+dfs)★
- codeforces 707 D Persistent Bookcase(dfs+bitset)
- Codeforces Round #368 (Div. 2) D. Persistent Bookcase(dfs)
- codeforces 707D Persistent Bookcase
- CodeForces 707D - Persistent Bookcase
- codeforces--707D. Persistent Bookcase
- Codeforces 353D Queue【思维】好题~
- Codeforces 343D Water Tree【思维+Dfs序+线段树】好题!
- 【21.28%】【codeforces 707D】Persistent Bookcase
- codeforces 707D Persistent Bookcase 离线+深搜
- Codeforces 707D Persistent Bookcase 暴力(bitset)
- Codeforces 667D World Tour【最短路+思维】好题!
- Codeforces 586D Phillip and Trains【思维+Bfs】好题~!
- Codeforces 466D Increase Sequence【思维】好题~
- C++第一次作业-选择与循环
- MFC使用控制台
- MVP在Android中简易易懂的实现案例
- 代码洁癖症的表现
- HashMap设计原理分析
- Codeforces 747D Persistent Bookcase【Dfs+思维】好题!好题!
- 冒泡排序和简单选择排序的回顾
- 先锋机器人pioneer-3DX主要类库函数
- Codeforces 781B 二分图
- BZOJ 2595 [Wc2008]游览计划 SPFA+斯坦纳树 or 插头DP
- 单链表中是否有环
- 编写一个简单的内核模块程序Hello World!
- 关于预测
- Linux网络编程学习笔记-简单点对点聊天程序--6