Codeforces Problem 707D Persistent Bookcase bitset+dfs

题目链接:codeforces.com/contest/707/problem/D

这个题用了比较巧妙的dfs 我们先来看 1,2,3 操作 这三个都很好做 我们维护1000个bitset  在相应的书架上进行操作就好  

关键是4操该如何维护 乍一看这像是维护历史信息 得用可持久化的数据结构 后来我看了题解之后豁然开朗

大家可以看链接:https://blog.csdn.net/queuelovestack/article/details/52269321

大概意思就是我们根据询问建立起来一颗dfs树  对于4操作 我们不用回去 只需要连接一条k到i的边 然后按dfs走就能保证正确性 

可以看看 那个博客的图 了解一下

#include<bits/stdc++.h>
using namespace std;
const int N = 1002;
const int M = 1e5+10;
bitset<N> b[N],c;
int h[M],to[M<<1],nex[M<<1],cur,op[M],l[M],r[M],ans[M];
void add_edge(int x,int y){
	to[++cur]=y;nex[cur]=h[x];h[x]=cur;
}
void dfs(int u){
	if(!u){
		for(int i = h[u]; i; i = nex[i]){
			int v = to[i];
			dfs(v);
		}
	}
	bool flag=false;
	if(op[u]==1){
		if(!b[l[u]].test(r[u])) flag=true,ans[u]++,b[l[u]].set(r[u]);
		for(int i = h[u]; i; i = nex[i]){
			int v = to[i];
			ans[v]=ans[u];
			dfs(v);
		}
		if(flag) b[l[u]].reset(r[u]);
	}else if(op[u]==2){
		if(b[l[u]].test(r[u])) flag=true,ans[u]--,b[l[u]].reset(r[u]);
		for(int i = h[u]; i; i = nex[i]){
			int v = to[i];
			ans[v]=ans[u];
			dfs(v);
		}
		if(flag) b[l[u]].set(r[u]);
	}else if(op[u]==3){
		ans[u]-=b[l[u]].count();
		b[l[u]]^=c;
		ans[u]+=b[l[u]].count();
		for(int i = h[u]; i; i = nex[i]){
			int v = to[i];
			ans[v]=ans[u];
			dfs(v);
		}
		b[l[u]]^=c;
	}else if(op[u]==4){
		for(int i = h[u]; i; i = nex[i]){
			int v = to[i];
			ans[v]=ans[u];
			dfs(v);
		}
	}
}
int main(){
	int n,m,q;
	scanf("%d%d%d",&n,&m,&q);
	for(int i = 1; i <= m; i++) c.set(i);
	for(int i = 1; i <= q; i++){
		scanf("%d",&op[i]);
		if(op[i]<3){
			scanf("%d%d",&l[i],&r[i]);
		}else scanf("%d",&l[i]);
		if(op[i]<4) add_edge(i-1,i);
		else  add_edge(l[i],i);
	}
	dfs(0);
	for(int i = 1; i <= q; i++) printf("%d\n",ans[i]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43824564/article/details/106249794
今日推荐