POJ 2443:Set Operation 经典位运算好题

Set Operation
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 2965   Accepted: 1196

Description

You are given N sets, the i-th set (represent by S(i)) have C(i) element (Here "set" isn't entirely the same as the "set" defined in mathematics, and a set may contain two same element). Every element in a set is represented by a positive number from 1 to 10000. Now there are some queries need to answer. A query is to determine whether two given elements i and j belong to at least one set at the same time. In another word, you should determine if there exist a number k (1 <= k <= N) such that element i belongs to S(k) and element j also belong to S(k).

Input

First line of input contains an integer N (1 <= N <= 1000), which represents the amount of sets. Then follow N lines. Each starts with a number C(i) (1 <= C(i) <= 10000), and then C(i) numbers, which are separated with a space, follow to give the element in the set (these C(i) numbers needn't be different from each other). The N + 2 line contains a number Q (1 <= Q <= 200000), representing the number of queries. Then follow Q lines. Each contains a pair of number i and j (1 <= i, j <= 10000, and i may equal to j), which describe the elements need to be answer.

Output

For each query, in a single line, if there exist such a number k, print "Yes"; otherwise print "No".

Sample Input

3
3 1 2 3
3 1 2 5
1 10
4
1 3
1 5
3 5
1 10

Sample Output

Yes
Yes
No
No

Hint

The input may be large, and the I/O functions (cin/cout) of C++ language may be a little too slow for this problem.

题意是给出了N个的集合,一个集合中有若干个数。然后是Q个询问,两个数是否在一个集合中。

发现一共最多就1000个集合,假设这个集合标号为N,那么能发现 h=N/32;k=N%32; h与k就可以对这个集合标号N进行标识了。所以用 a[h][j]= k 表示j这个数在 h*32 + (k二进制位为1的那个标识位) 这个集合中。

然后询问两个数是否在一个集合中,只需询问在h相同的情况下,两个k1,k2相与是否大于0,大于0说明存在两个都是1的位置,就说明这两个数曾在一个集合中了。

代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;

int a[32][10001];
int n,q;

int main()
{
	int i,j,f,h,k,num;
	bool flag;
	memset(a,0,sizeof(0));
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&f);
		h=i%32;
		k=i/32;
		for(j=1;j<=f;j++)
		{
			scanf("%d",&num);
			a[h][num] = a[h][num]|(1<<k);
		}
	}
	scanf("%d",&q);
	for(i=1;i<=q;i++)
	{
		scanf("%d%d",&h,&k);
		flag=false;
		for(j=0;j<32;j++)
		{
			if(a[j][h]&a[j][k])
			{
				flag=true;
				break;
			}
		}
		if(flag)
			printf("Yes\n");
		else
			printf("No\n");
	}
  
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

posted on 2015-09-29 12:54  光速小子  阅读(152)  评论(0编辑  收藏  举报

导航