QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#618110#1869. Power Station of ArtpzjQWQWA 466ms59048kbC++143.2kb2024-10-06 18:51:072024-10-06 18:51:08

Judging History

你现在查看的是最新测评结果

  • [2024-10-06 18:51:08]
  • 评测
  • 测评结果:WA
  • 用时:466ms
  • 内存:59048kb
  • [2024-10-06 18:51:07]
  • 提交

answer

/*
不补题的报应啊
为了符合交换的形式,我们把二操作转化为:
交换之后取反
考虑 a->b->c 操作之后会变成什么:
我们从 a[a],a[b],a[c] 和 c[a],c[b],c[c] 中变成了 a[c],a[b],a[a] 和 c[c],c[b],c[a]
也就是说,两个距离为 2 的点之间能随意交换信息
对每个连通块分别考虑,讨论它们是不是二分图
- 不是二分图:
那么一定有奇环,发现图上任意两点都能直接交换
那么把这些提出来然后比较信息是否全部相同
因为可以取反交换,所以只关注 first 而不关注 second
草了,你需要让需要改的个数恰好是偶数个
- 是二分图:
同一部之间可以互相交换
所以情况就有同一部之间交换消除,不同部之间最后再来交换
只需要判对面部交换后和需求的相同的加上自己部和需求相同的数量是否等于该需求的数量加上对面交换后需求的数量
*/
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N=1e6+5;
int T,n,m,col[N];
bool flag,vis[N];
vector<int> G[N];
pair<int,int> a[N],b[N];
map<int,bool> flg;
map<pair<int,int>,int> cnt[4],mp[2];
pair<int,int> upd(pair<int,int> a){ return make_pair(a.first,1-a.second); }
void color(int u){
	if(flag) return;
	for(auto v:G[u]){
		if(col[v]==col[u]){
			flag=1;
			return;
		}
		if(~col[v]) continue;
		col[v]=1-col[u];
		color(v);
	}
}
void dfs(int u){	
	++mp[0][a[u]],++mp[1][b[u]];
	vis[u]=1,col[u]=0;
	for(auto v:G[u]){
		if(vis[v]) continue;
		dfs(v);
	}
}
void work(int u){
	++cnt[col[u]][a[u]],++cnt[col[u]+2][b[u]];
	vis[u]=1;
	for(auto v:G[u]){
		if(vis[v]) continue;
		work(v);
	}
}
void check(){
	for(int i=1;i<=n;++i) col[i]=-1,vis[i]=0;
	for(int i=1;i<=n;++i) if(col[i]==-1){
		flag=0,col[i]=0;
		color(i);
		if(flag){
			mp[0].clear(),mp[1].clear();
			dfs(i);
			int cnt=0;
			for(auto it:mp[0]){
				if((mp[0].count(upd(it.first))?mp[0][upd(it.first)]:0)+it.second!=mp[1][it.first]+mp[1][upd(it.first)]){
					cout<<"NO"<<endl;
					return;
				}
				if(!flg[it.first.first]) cnt+=abs(it.second-mp[1][it.first]),flg[it.first.first]=1;
			}
			flg.clear();
			if(cnt&1){
				cout<<"NO"<<endl;
				return;
			}
		} else{
			cnt[0].clear(),cnt[1].clear(),cnt[2].clear(),cnt[3].clear();
			work(i);
			for(auto it:cnt[0]) if(cnt[1][upd(it.first)]+it.second!=cnt[2][it.first]+cnt[3][upd(it.first)]){
				cout<<"NO"<<endl;
				return;
			}
			for(auto it:cnt[1]) if(cnt[0][upd(it.first)]+it.second!=cnt[3][it.first]+cnt[2][upd(it.first)]){
				cout<<"NO"<<endl;
				return;
			}
		}
	}
	cout<<"YES"<<endl;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>T;
	while(T--){
		cin>>n>>m;
		for(int i=1,u,v;i<=m;++i){
			cin>>u>>v;
			G[u].emplace_back(v);
			G[v].emplace_back(u);
		}
		for(int i=1;i<=n;++i) cin>>a[i].first;
		for(int i=1;i<=n;++i){
			char c;
			cin>>c;
			if(c=='R') a[i].second=1;
			else a[i].second=0;
		}
		for(int i=1;i<=n;++i) cin>>b[i].first;
		for(int i=1;i<=n;++i){
			char c;
			cin>>c;
			if(c=='R') b[i].second=1;
			else b[i].second=0;
		}
		check();
		for(int i=1;i<=n;++i) G[i].clear(),G[i].shrink_to_fit();
	}
	return 0;
}

详细

Test #1:

score: 100
Accepted
time: 4ms
memory: 32256kb

input:

3
2 1
1 2
3 4
RR
4 3
BB
3 2
1 2
2 3
1 1 1
RBR
1 1 1
BBB
3 3
1 2
2 3
3 1
1 1 1
RBR
1 1 1
BBB

output:

YES
NO
YES

result:

ok 3 lines

Test #2:

score: -100
Wrong Answer
time: 466ms
memory: 59048kb

input:

25054
5 10
4 5
4 2
4 3
4 1
5 2
5 3
5 1
2 3
2 1
3 1
12 2 9 10 7
RRRBB
10 2 9 7 12
RRBRB
1 0
4
R
4
R
8 4
4 3
1 5
8 5
6 5
7 2 11 10 9 6 3 5
RBRBBRBR
7 2 10 11 6 5 3 9
RBRBBRBR
7 4
7 2
5 1
5 6
5 4
12 5 9 14 5 12 12
RRBRBRR
14 12 9 5 12 12 5
RBBRBRB
10 1
4 6
5 3 2 9 7 3 11 11 6 8
RRRBRRBBBR
5 3 2 3 7 9 1...

output:

YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
YES
NO
YES
NO
NO
YES
YES
YES
NO
YES
NO
YES
YES
NO
YES
YES
NO
YES
NO
YES
YES
YES
YES
NO
YES
YES
NO
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
NO
YES
NO
YES
YES
YES
YES
NO
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
YES
YES
YES
NO
YES
NO
NO...

result:

wrong answer 113th lines differ - expected: 'YES', found: 'NO'