专栏文章

【0】做题心得 - 2025 NOIP #64 - T2【bitset】

题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@min5drua
此快照首次捕获于
2025/12/01 20:50
3 个月前
此快照最后确认于
2025/12/01 20:50
3 个月前
查看原文
离正解就差一个 bitset。你会发现一个性质就是直接把确定发生的往下扔一定是对的,要是一个已经发生了且它的前驱没有一个是可以不经过 vv 就能发生,那么显然此时会导致 vv 自己也是对的。这个写出来容易做到 O(nm+qn2)\mathcal O(nm+qn^2),超时。发现数据范围不是人 2×1092\times 10^9 有两只怎么办呢发现经典 bitset 哦这扯不扯。
CPP
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e4+10;
int n,m,q,deg[2][N];
bitset<N>ans,upset[N],downset[N];
vector<int>e[N],g[N];
queue<int>Q;
int main(){
	freopen("graph.in","r",stdin);
	freopen("graph.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m>>q;
	for(int i=1;i<=m;i++){
		int u,v;
		cin>>u>>v;
		e[u].push_back(v), deg[0][v]++;
		g[v].push_back(u), deg[1][u]++;
	}
	for(int i=1;i<=n;i++)if(!deg[1][i])
		Q.push(i);
	while(Q.size()){
		int p=Q.front();
		Q.pop();
		upset[p][p]=1;
		for(auto v:g[p]){
			if(!(--deg[1][v]))Q.push(v);
			upset[v]|=upset[p];
		}
	}
	for(int i=1;i<=n;i++)if(!deg[0][i])
		Q.push(i);
	else
		downset[i].set();
	while(Q.size()){
		int p=Q.front();
		Q.pop();
		downset[p]|=upset[p];
		for(auto v:e[p]){
			if(!(--deg[0][v]))Q.push(v);
			downset[v]&=downset[p];
		}
	}
	while(q--){
		int k;
		cin>>k;
		ans.reset();
		while(k--){
			int p;
			cin>>p;
			ans|=downset[p];
		}
		for(int i=1;i<=n;i++)
			if(ans[i]) cout<<i<<" ";
		cout<<"\n";
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...