QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#655008#7755. Game on a ForestTomgao4116WA 6ms22300kbC++203.1kb2024-10-18 23:43:182024-10-18 23:43:20

Judging History

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

  • [2024-10-18 23:43:20]
  • 评测
  • 测评结果:WA
  • 用时:6ms
  • 内存:22300kb
  • [2024-10-18 23:43:18]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<long long,long long> pll;
vector<ll> a[500005];
ll vis[500005];
ll cnt[500005]; 
ll sum[500005];
ll pre[500005];
ll f[500005];
ll d[500005];
//每个子树点的异或值:sum[i] 
//子树下面多个子树合并的异或值:pre[i] 
//以点i为根的子树节点个数cnt[i] 
//标号:f[i]:代表第i个点是属于那个点为根的子树:
//标号dfs: 
ll val=0,ans=0; 
void dfs1(ll ver){
	vis[ver]=1;
	for(int i=0;i<a[ver].size();i++){
		ll nxt=a[ver][i];
		if(vis[nxt]==0){
			f[nxt]=f[ver];
			dfs1(nxt);
		}
	}
} 
//预处理dfs 
void dfs2(ll ver){
	cnt[ver]=1;
	vis[ver]=1;
	pre[ver]=0; 
	for(int i=0;i<a[ver].size();i++){
		ll nxt=a[ver][i];
		if(vis[nxt]==0){
			dfs2(nxt);
			cnt[ver]+=cnt[nxt];
			pre[ver]^=sum[nxt];
		}
	}
	//下面子节点个数是奇数:下面sg值为1 
	if(cnt[ver]%2==1){
		sum[ver]=1; 
	//下面子节点个数是偶数:下面sg值为2:	
	}else{
		sum[ver]=2;
	}
}
void dfs3(ll ver,ll root){
	vis[ver]=1;
//	cout<<"ver: "<<ver<<endl;
	for(int i=0;i<a[ver].size();i++){
		ll nxt=a[ver][i];
		if(vis[nxt]==0){
			dfs3(nxt,root);
			ll down=cnt[nxt];
			ll up=cnt[root]-cnt[nxt];
			if(down%2==1){
				down=1;
			}else{
				down=2;
			}
			if(up%2==1){
				up=1;
			}else{
				up=2;
			}
		//	cout<<up<<" "<<down<<endl;
			//如果删去这条边后的状态异或和能赢:----代表第二个要输:所以这时候的异或和要为0 对答案的贡献+1; 
			if((val^sum[root]^up^down)==0)ans++;
		}
	}
}
void dfs4(ll ver,ll root){
	vis[ver]=1;
	ll up=cnt[root]-cnt[ver];
	//若为最顶上的节点: 
	if(up==0){
		if((val^sum[root]^pre[ver])==0)ans++;
	//为最底下叶子节点:	
	}else if(up==cnt[root]-1){
		if(up%2==1){
			up=1;
		}else{
			up=2;
		}
		if((val^sum[root]^up)==0)ans++;
	//为中间节点: 
	}else{
		if(up%2==1){
			up=1;
		}else{
			up=2;
		}
		if((val^sum[root]^up^pre[ver])==0)ans++;
	}
	for(int i=0;i<a[ver].size();i++){
		ll nxt=a[ver][i];
		if(vis[nxt]==0){
			dfs4(nxt,root);
		}
	}
}
int main(){
	ll n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)f[i]=i;
	for(int i=1;i<=m;i++){
		ll u,v;
		cin>>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);
	}
	//dfs:判断每个节点属于哪个子树+做好根节点的标号: 
	for(int i=1;i<=n;i++){
		if(!vis[i]){
			dfs1(i);
		}
	}
	memset(vis,0,sizeof(vis));
	//1:先预处理出树上的前缀异或和+子树节点数目:
	for(int i=1;i<=n;i++){
		//从森林中每个子树的根节点进入dfs预处理: 
	//	cout<<i<<" "<<f[i]<<endl; 
		if(!vis[i]&&f[i]==i){
			dfs2(i);
			if(cnt[i]%2==1){
				val^=1;
			}else{
				val^=2;
			}
		} 	
	}
	//1:枚举删边:
	memset(vis,0,sizeof(vis)); 
	for(int i=1;i<=n;i++){
		if(!vis[i]&&f[i]==i){
			dfs3(i,i);
		}
	}
//	cout<<ans<<endl;
	//2:枚举删点: 
	memset(vis,0,sizeof(vis)); 
	for(int i=1;i<=n;i++){
		//1:1个点单独处理: 
		if(cnt[i]==1){
			if((val^1)==0)ans++;
			continue;
		}
		if(!vis[i]&&f[i]==i){
			dfs4(i,i);
		}
	}
	cout<<ans;
	return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 2ms
memory: 15700kb

input:

3 1
1 2

output:

2

result:

ok 1 number(s): "2"

Test #2:

score: 0
Accepted
time: 5ms
memory: 15748kb

input:

4 3
1 2
2 3
3 4

output:

3

result:

ok 1 number(s): "3"

Test #3:

score: 0
Accepted
time: 0ms
memory: 19736kb

input:

100000 1
4647 17816

output:

1

result:

ok 1 number(s): "1"

Test #4:

score: 0
Accepted
time: 0ms
memory: 17760kb

input:

100000 2
64075 72287
63658 66936

output:

0

result:

ok 1 number(s): "0"

Test #5:

score: 0
Accepted
time: 3ms
memory: 15668kb

input:

100000 3
59930 72281
31689 59132
20469 33165

output:

3

result:

ok 1 number(s): "3"

Test #6:

score: 0
Accepted
time: 4ms
memory: 21916kb

input:

100000 10
20391 78923
27822 80617
21749 25732
12929 79693
42889 52515
59064 99869
29031 41875
4463 17813
13407 42498
19120 20957

output:

0

result:

ok 1 number(s): "0"

Test #7:

score: 0
Accepted
time: 4ms
memory: 20364kb

input:

99999 101
34378 94161
67696 83255
24557 25591
11476 58475
5684 38157
33843 35321
9046 24028
14293 77681
587 42098
9402 27228
6999 13980
27118 84005
3622 8353
13545 51621
16998 63647
32912 53178
15206 15815
56517 86335
5563 93770
153 278
11242 41753
75098 76792
1695 22836
25936 33352
2765 6778
19597 ...

output:

200

result:

ok 1 number(s): "200"

Test #8:

score: 0
Accepted
time: 6ms
memory: 20040kb

input:

100000 1001
298 77037
4590 12413
23983 44856
15445 16769
81205 99801
62678 90775
7513 11129
27455 63264
39986 44211
61692 72309
60465 67632
66675 72861
4281 28582
26376 65551
9751 60666
4388 47945
1077 1132
53716 62874
39894 55139
28957 63412
41201 89573
6166 10477
2322 23039
24579 87570
16337 90895...

output:

1001

result:

ok 1 number(s): "1001"

Test #9:

score: 0
Accepted
time: 4ms
memory: 18148kb

input:

100000 2000
15502 16605
10164 34454
48764 97837
3462 26651
32457 52288
2871 13083
9012 55876
45290 81448
2879 15152
5347 6203
14519 50871
4513 19513
15241 25215
18759 76715
53123 97123
10178 25478
1955 4281
2346 30453
1770 53064
38900 57761
51275 65969
4801 21613
655 1131
15956 52140
39128 47232
416...

output:

0

result:

ok 1 number(s): "0"

Test #10:

score: -100
Wrong Answer
time: 4ms
memory: 22300kb

input:

99999 3000
27340 79581
55921 68664
459 1145
55880 59400
25884 34981
27695 55440
15559 31392
16400 51581
7299 22688
24107 72852
16642 62108
5610 36856
19456 38723
50096 89933
44262 85879
25331 25638
38103 72312
58090 61238
10581 65561
4612 6491
11386 21234
29353 90524
8877 67738
48566 69766
26900 320...

output:

97271

result:

wrong answer 1st numbers differ - expected: '94369', found: '97271'