【dfs】【模拟】I Like Matrix Forever!

对一个 n ∗ m 的零矩阵 A 进行 q 次操作:
• 1 i j:将 Ai,j 取反;
• 2 i:将矩阵 A 第 i 行的所有元素全部取反;
• 3 j:将矩阵 A 第 j 列的所有元素全部取反;
• 4 k:将矩阵 A 还原为第 k 次操作之后的状态。
进行每一次操作之后,询问当前矩阵所有元素的和。

Input

第一行包含三个整数 n,m 和 q。
之后 q 行每行包含两个或三个整数,表示一次操作的所有参数。

Output

共 q 行每行包含一个整数 ans,表示当前矩阵所有元素的和。


这是一个需要快读快输的玩意儿。。。
主要是模拟,然后建立处理时间的关系。(比如4操作的话直接在回到的那个点继续搜什么的)然后处理完每一步返回,每一步计算,最后用一个Ans存起来。

#include<cstdio>
int l[100005],Ans[100005],n,m,k,f[1005][1005],tt,C[100005],X[100005],Y[100005],Sum;
struct asdf{
	int to,next;
} lu[100005];
int read(){   //快读
	char cc=getchar();
	int x=0;
	while(cc>'9'||cc<'0') cc=getchar();
	while(cc>='0'&&cc<='9'){
		x=x*10+cc-48;
		cc=getchar();
	}
	return x;
}
void put(int l){    //快输
	if(l>9) put(l/10);
	putchar(l%10+48);
}
void G(int kk){      //处理/回溯
	if(C[kk]==1){
		Sum+=1-(f[X[kk]][Y[kk]]<<1);   //神奇玩意
		f[X[kk]][Y[kk]]^=1;
	}
	else if(C[kk]==2)
		for(int i=1;i<=m;++i){
			Sum+=1-(f[X[kk]][i]<<1);
			f[X[kk]][i]^=1;
		}
		  
	else if(C[kk]==3)
	    for(int i=1;i<=n;++i){
	    	Sum+=1-(f[i][X[kk]]<<1);
	    	f[i][X[kk]]^=1;
	    }
}
void s(int kk){   //dfs
	G(kk);
	Ans[kk]=Sum;
	for(int i=l[kk];i;i=lu[i].next)  //它接下来要处理的命令编号
	  s(lu[i].to);
	G(kk);
}
void lj(int aa,int bb){   //将aa结点与bb结点链接,说明aa处理完后可以处理bb
	lu[++tt].to=bb;
	lu[tt].next=l[aa];
	l[aa]=tt;
}
int main(){
	int t;
	n=read();
	m=read();
	k=read();
	for(int i=1;i<=k;++i){   //i,命令序号
		C[i]=read();X[i]=read();  //随意的一个读入。
		if(C[i]==1) Y[i]=read();
		if(C[i]==4) lj(X[i],i);   //如果需要回溯,那么回溯到的那个点可以直接处理此操作。。。
		else lj(i-1,i);    //不然就从上一步到这里
	}
	s(0);   //注意有一些是回溯到0号命令的 
	for(int i=1;i<=k;++i,putchar('\n'))  //快输
	  put(Ans[i]);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值