问题 A: 世界线
时间限制: 1 Sec 内存限制: 256 MB
题面
题面谢绝公开。
题解
我刚学完bitset就考了???然而我赛时并没有想到是bitset……
话说我bitset还是没有颓完啊赶紧去补一波时空复杂度……
bitset优化暴力(据某诺神说这是bitset果题??)
注意dfs的时侯如果目标节点已经搜过了直接用当前节点的bitset或上目标节点的bitset值即可。
还有$6e4×6e4$会炸空间。开一个$6e4×3e2$的然后一半一半跑即可。
至于怎么跑一半,直接判断和n/2的关系即可。
具体实现看代码。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<stack> #include<cmath> #include<algorithm> #include<bitset> #define rint register int #define read(A) A=init() #define MAXN 60050 #define MAXM 100050 using namespace std; inline int init() { int a=0,b=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)b=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){a=(a<<3)+(a<<1)+ch-‘0‘;ch=getchar();} return a*b; } bitset <MAXN/2> bit[MAXN]; int n,m,mid,du[MAXN];//read long long ans;//write int tot,first[MAXN],v[MAXM],nxt[MAXM];//front-star bool dev,vis[MAXN]; inline void add(int uu,int vv) { v[++tot]=vv,nxt[tot]=first[uu],first[uu]=tot; } inline void dfs(int x) { vis[x]=1; if(!dev){if(x<=mid)bit[x].set(x);} else {if(x>mid)bit[x].set(x-mid);} for(rint i=first[x];i;i=nxt[i]) { if(!vis[v[i]])dfs(v[i]); bit[x]|=bit[v[i]]; } return ; } int main() { read(n),read(m); for(rint i=1,in_u,in_v;i<=m;++i) read(in_u),read(in_v),add(in_u,in_v),du[in_v]++; mid=n/2;dev=0; for(rint i=1;i<=n;++i)if(!du[i])dfs(i); for(rint i=1;i<=n;++i) { ans+=bit[i].count(); bit[i].reset(); } memset(vis,0,sizeof(vis)); dev=1; for(rint i=1;i<=n;++i)if(!du[i])dfs(i); for(rint i=1;i<=n;++i)ans+=bit[i].count(); cout<<ans-n-m<<endl; }
原文地址:https://www.cnblogs.com/xingmi-weiyouni/p/11515992.html
时间: 2024-11-06 07:10:14