BZOJ3189 : [Coci2011] Slika

Slika

题意:
在这里插入图片描述
在这里插入图片描述

首先,题目有一个外衣,就是操作有版本的概念,他会进行存档和读档操作,但是我们知道,我们把操作建成一个树,他读档就是回到一个祖先,而对最终形态有影响的只有当前点到根的叠加操作。
那么我们就建一棵树,维护一个fa数组,最后不断跳祖先就知道了有效操作及顺序。
做法一:
用并查集维护当前行没染色的最右边的点。
我们把操作,逆序搞,因为后面染色的会覆盖前面染色的操作。
然后呢对于一段染过色的区间是不会被重复遍历的。
那么总的复杂度就是( m ∗ n + n ∗ n m*n+n*n mn+nn)。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,n,m) for(int i=n;i<=m;i++)
#define repp(i,n,m) for(int i=n;i>=m;i--)

int n,k,m;
char op[10];
int sa[100040];
int cnts=0,tot=0;
struct node{
	int cl;
	int x1,y1,x2,y2;
}z[100040];
queue<int>q;
int f[100050];
int fa[1010][1010];
int col[1004][1004];
int find(int x,int i){
	if(x==fa[i][x])return x;
	return fa[i][x]=find(fa[i][x],i);
}
int main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin>>n>>k>>m;
	int now=0;
	for(int i=1;i<=m;i++){
		cin>>op;
		if(op[0]=='P'){
			tot++;
			cin>>z[tot].cl>>z[tot].x1>>z[tot].y1>>z[tot].x2>>z[tot].y2;
			f[tot]=now;
			now=tot;
		}else if(op[0]=='S'){
			cnts++;
			sa[cnts]=now;
		}else{
			int a;
			cin>>a;
			now=sa[a];
		}
	}
	for(int i=0;i<n+2;i++){
		for(int j=0;j<n+2;j++)col[i][j]=1,fa[i][j]=j;
	}
	while(now){
		int u=now;
		for(int i=z[u].x1;i<=z[u].x2;i++){
			int p;
			if((i-z[u].x1)%2==0)p=find(z[u].y1,i);
			else p=find(z[u].y1+1,i);
			
			for(int j=p;j<=z[u].y2;j=find(j+2,i)){
				fa[i][j]=j+2;
				col[i][j]=z[u].cl;
			}
		}
		now=f[now];
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++)cout<<col[i][j]<<" ";
		cout<<"\n";
	}
	return 0;
}

做法二:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值