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

lenlen
一如既往,萬事勝意.搬运于
2025-08-24 22:17:42,当前版本为作者最后更新于2022-10-31 21:07:02,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
前言
本蒟蒻刚刚学完高斯消元,
拿这个题试试水。推荐一下个人博客:高斯消元学习笔记。
Problem
题目大意:每一只始祖鸟要么在上游,要么在下游,而每一只始祖鸟认识一些始祖鸟,要求他在的地方他所认识的始祖鸟的个数为偶数。
数据范围: 。
Solution
我们考虑要满足第 只始祖鸟需要满足什么条件,我们可以把每一只始祖鸟分为奇数个朋友和偶数个朋友 2 类,并且定义 表示第 只始祖鸟去了上游, 表示第 只始祖鸟去了下游,并定义 的朋友分别为 。
-
当第 只始祖鸟的朋友数为偶数时,显然我们必须保证 $x_{a_{i,1}} \oplus x_{a_{i,2}} \oplus \cdots \oplus x_{a_{i,k}}=1$,这样无论 去哪里都能满足条件。
-
当第 只始祖鸟的朋友数为偶数时,显然我们必须保证 $x_{a_{i,1}} \oplus x_{a_{i,2}} \oplus \cdots \oplus x_{a_{i,k}}=1$ 且 或者 $x_{a_{i,1}} \oplus x_{a_{i,2}} \oplus \cdots \oplus x_{a_{i,k}}=0$ 且 ,显然可以综合一下即 $x_{a_{i,1}} \oplus x_{a_{i,2}} \oplus \cdots \oplus x_{a_{i,k}} \oplus x_i=1$。
然后就是异或高斯消元的模板题了。
当然本题还有一些注意事项(
也可能是只有我掉坑里了):-
这个题的话因为若有不唯一解也是可以随便输出一个解的,所以当遇到一个主元系数都为 0 时是跳过而非退出,并且假设前面已经处理了 个主元,而现在正在处理第 个主元,那么要从 开始寻找是否有第 位为 1 的方程。
对于第二点,在这个题里面,好像不考虑也能过,我提供一组 hack 数据:
6 3 4 5 6 2 1 6 0 2 3 6 0 0貌似题解区的几位公布了全部源码的几篇题解都被 hack 了,大家可以自己去推一下,看看自己输出的答案满不满足:
$$\begin{cases} & x_1 \oplus x_4 \oplus x_5 \oplus x_6=1\\ & x_1 \oplus x_6=0\\ & x_3 \oplus x_6=0 \end{cases}$$Code
代码如下:
#include<bits/stdc++.h> using namespace std; const int N=2732; int n,m,x,ans; bitset<N>a[N]; void gauss() { int cnt=0; for(int i=1;i<=n;i++) { int maax=cnt+1;//就是我所说的第二个点,如果写法不同说不定这个问题就自动考虑进去了 for(int j=i+1;j<=n;j++) if(a[j][i]>a[maax][i]) maax=j; swap(a[cnt+1],a[maax]); if(!a[i][i]) continue; cnt++; for(int j=1;j<=n;j++) if(a[j][i]==1&&i!=j)a[j]=a[j]^a[i]; } if(cnt<n) { for(int i=1;i<=n;i++) if(!a[i][i]&&a[i][n+1]) { printf("Impossible\n"); exit(0); } } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&m); if(m&1) a[i][n+1]=1,a[i][i]=1; while(m--) scanf("%d",&x),a[i][x]=1; } gauss(); for(int i=1;i<=n;i++) if(a[i][n+1]) ans++; printf("%d\n",ans); for(int i=1;i<=n;i++) if(a[i][n+1]) printf("%d ",i); } -
- 1
信息
- ID
- 5149
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者