B. Gardener and the Array

B. Gardener and the Array

The gardener Kazimir Kazimirovich has an array of n integers c1,c2,,cn.

He wants to check if there are two different subsequences a and b of the original array, for which f(a)=f(b), where f(x) is the bitwise OR of all of the numbers in the sequence x.

A sequence q is a subsequence of p if q can be obtained from p by deleting several (possibly none or all) elements.

Two subsequences are considered different if the sets of indexes of their elements in the original sequence are different, that is, the values of the elements are not considered when comparing the subsequences.

Input

Each test contains multiple test cases. The first line contains the number of test cases t (1t105). The description of the test cases follows.

The first line of each test case contains one integer n (1n105) — the size of the array c.

The description of the array c in this problem is given implicitly to speed up input.

The (i+1)-st of the following n lines of the test case begins with an integer ki (1ki105) — the number of set bits in the number ci. Next follow ki distinct integers pi,1,pi,2,,pi,ki (1pi2105) —the numbers of bits that are set to one in number ci. In other words, ci=2pi,1+2pi,2++2pi,ki.

It is guaranteed that the total sum of ki in all tests does not exceed 105.

Output

For each set of input, print "Yes" if there exist two different subsequences for which f(a)=f(b), and "No" otherwise.

You can output the answer in any case (upper or lower). For example, the strings "yEs", "yes", "Yes", and "YES" will be recognized as positive responses.

Example

input

复制代码
5
3
2 1 5
2 2 4
2 2 3
2
2 1 2
1 2
4
3 1 2 4
2 2 4
4 1 2 5 6
2 2 5
5
3 3 1 2
3 2 5 3
5 7 2 3 1 4
5 1 2 6 3 5
3 2 6 3
2
1 1
1 2
复制代码

output

No
Yes
Yes
Yes
No

Note

It can be proven that in the first test case there are no two different subsequences a and b for which f(a)=f(b).

In the second test case, one of the possible answers are following subsequences: the subsequence a formed by the element at position 1, and the subsequence b formed by the elements at positions 1 and 2.

In the third test case, one of the possible answers are following subsequences: the subsequence a formed by elements at positions 1, 2, 3 and 4, and the subsequence b formed by elements at positions 2, 3 and 4.

 

解题思路

  感觉官方给出的题解写得不是很好,给出的证明跟没证一样。

  首先容易想到,如果存在两个数x,y各自在二进制下为1的位所构成的集合属于包含关系,例如x=21+23+34在二进制下为1的位所构成的集合为{1,3,4}y=21+24对应的集合为{1,4},那么存在包含关系{1,4}{1,3,4},为了方便这里标记为xy。那么我们就可以构造出一组解,其中子数组a取全集U(即全部的数),子数组bU{x}(这里假设xy),很明显abf(a)=f(b)(这里的a,b指的是数的集合)。

  这就证明了如果存在两个数的二进制位属于包含关系,那么有解。上面证明了充分性,题解只通过充分性就推出“如果不存在两个数的二进制位属于包含关系,那么无解”,很明显逻辑有问题,因此还要证明这个命题的必要性,即“如果有解,那么存在两个数的二进制位属于包含关系”,从而根据逆否命题推出等价命题“如果不存在两个数的二进制位属于包含关系,那么无解”。

  如果有解,那么存在子数组ab满足abf(a)=f(b)。那么有

f(U)=f(b(Ub))=f(b)f(Ub)=f(a)f(Ub)=f(a(Ub))=f(ab¯)=f((ab¯)U)=f((ab¯)(bb¯))=f(abab¯b¯)=f(abb¯(aU))=f(ab(Ub))

  其中保证aϕbϕ

  通过上面的推导可以得到f(U)=f(ab(Ub)),并且由于ab,因此ab(Ub)U(反证法,如果ab(Ub)=U,由于ab(Ub)=ab(Ub¯)=abb¯=U,而bb¯=U,因此ab=b,即a=b,矛盾),意味着至少存在两个数的二进制位属于包含关系。这是因为将被包含的数从全集U中删除,得到真子集ab(Ub),同时还满足f(U)=f(ab(Ub))。必要性得到证明。

  因此得到证明:如果存在两个数的二进制位属于包含关系 有解,从而可以推出逆否命题:如果不存在两个数的二进制位属于包含关系,那么无解。

  因此接下来只需要开个哈希表枚举统计每个数在二进制下为1的位出现的次数,然后再枚举每个数,看看该数能否被其他数包含(等价于看看该数在二进制下所有是1的位在哈希表中出现次数是否都大于等于2),如果是那么就存在解。如果全部数都无法被其他数包含那么就无解。

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1e5 + 10;
 5 
 6 vector<int> p[N];
 7 
 8 void solve() {
 9     int n;
10     scanf("%d", &n);
11     unordered_map<int, int> cnt;
12     for (int i = 0; i < n; i++) {
13         int m;
14         scanf("%d", &m);
15         p[i].clear();
16         while (m--) {
17             int x;
18             scanf("%d", &x);
19             cnt[x]++;
20             p[i].push_back(x);
21         }
22     }
23     for (int i = 0; i < n; i++) {
24         bool flag = true;
25         for (auto &x : p[i]) {
26             if (cnt[x] < 2) {
27                 flag = false;
28                 break;
29             }
30         }
31         if (flag) {
32             printf("Yes\n");
33             return;
34         }
35     }
36     printf("No\n");
37 }
38 
39 int main() {
40     int t;
41     scanf("%d", &t);
42     while (t--) {
43         solve();
44     }
45     
46     return 0;
47 }
复制代码

 

参考资料

  Codeforces Round #843 (Div. 2) Editorial:https://codeforces.com/blog/entry/111286

posted @   onlyblues  阅读(95)  评论(5编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示