1 条题解
-
0
自动搬运
来自洛谷,原作者为

fish_love_cat
「要毁灭世界,根本不需要邪恶。起初,那些都是不会被任何人怪罪的小小愿望。而那样的愿望却如此轻易地,和末日相连在一起。」搬运于
2025-08-24 23:10:57,当前版本为作者最后更新于2025-03-09 19:59:25,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
没打比赛,赛后独立做出来的。
首先可以搞个桶上去。
然后跑线性筛,把每个质数视作一个点进行连边。
这样就建了图。
糊个并查集上去判掉不连通的情况。剩余问题离线出来,按照连通块排序。
容易发现一个限制能做当且仅当所在连通块能异或出指定数。
所以对于每个连通块的问题可以搞个线性基处理。
做完了。
代码:
#include<bits/stdc++.h> using namespace std; #define int long long const int MB=60; int a[500005],flc[10000005],fa[10000005],p[MB+5],d[MB+5],top,N; bool aa[10000005],ans[500005],vis[10000005]; vector<int>ve[10000005]; struct fish{ int u,v,z; int id; int fa; }Q[500005]; void ins(int x){ if(!x)return; for(int i=MB;i>=0;i--) if((1ll<<i)&x){ if(!p[i]){p[i]=x;break;} else x^=p[i]; } } bool ask(int x){ for(int i=MB;i>=0;i--) if((1ll<<i)&x)x^=p[i]; return x==0; } int find(int x){ return(x==fa[x]?x:fa[x]=find(fa[x])); } void zss(int n){ for(int i=2;i<=n;i++) if(!aa[i]){ for(int j=1;j*i<=n;j++){ aa[j*i]=true; if(flc[j*i]!=-1) fa[find(j*i)]=find(i); } } } bool cmp(fish x,fish y){ return x.fa<y.fa; } void news(int x){ memset(p,0,sizeof p); memset(d,0,sizeof d); for(int i=0;i<ve[x].size();i++)ins(flc[ve[x][i]]); } signed main(){ int n,q; cin>>n; for(int i=1;i<=n;i++)cin>>a[i],N=max(N,a[i]); for(int i=1;i<=N;i++)fa[i]=i,flc[i]=-1; for(int i=1,x;i<=n;i++)cin>>x,flc[a[i]]=x; zss(N); cin>>q; for(int i=1;i<=q;i++){ int u,v,z; cin>>u>>v>>z; if(find(u)!=find(v))continue; Q[++top].u=u,Q[top].v=v,Q[top].z=z,Q[top].id=i,Q[top].fa=find(u); vis[find(u)]=1; } sort(Q+1,Q+1+top,cmp); for(int i=1;i<=N;i++) if(vis[find(i)])ve[find(i)].push_back(i); for(int i=1;i<=top;i++){ if(Q[i].fa!=Q[i-1].fa)news(Q[i].fa); if(ask(Q[i].z))ans[Q[i].id]=1; } for(int i=1;i<=q;i++)puts((ans[i]?"Yes":"No")); return 0; }本来写了 123 行,太难读了,于是现在只有 71 行。
效率比较低劣,跑了 40s 以上。
注意建图和并查集的一些细节。
提交记录。
建议评蓝或紫。
- 1
信息
- ID
- 11457
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 5
- 标签
- (无)
- 递交数
- 0
- 已通过
- 0
- 上传者