压位加速-poj-2443-Set Operation
题目链接:
http://poj.org/problem?id=2443
题目意思:
有n个集合(n<=1000),每个集合有m个数ai(m<=10000,1=<ai<=10000),同一个集合中可能有相同的数.有q个查询(q<=200000),对于每个查询a,b,问是否存在一个集合同时包含a和b.
解题思路:
题目意思很简单,但时间和内存限制比较大,需要压位加速处理。
两种解法
解题思路一:
将每一个集合看成是一行,也成了一个1000*10000的0、1矩阵,对于每个数来书,它所在的列的0、1分布情况也就是它所在集合的情况。但问题是现在一共有1000行,2^1000肯定不行,但考虑到一个int可以存32位(2^32),1000<32*32,所以可以开32个整数,每个整数的二进制的每一位代表每一行,这样就可以在q*32的可接受的时间复杂度内查询出结果。将扫描1000变为扫描32,利用整数的位操作减少为1/32。
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; #define Maxn 11000
int sa[Maxn][35];//sa[i][j]表示i这个数在[32*j,32*j+31]集合区间的出现情况
//一个int可以保存32个集合的信息,一共只有1000个集合所有只用32个整型即可 int main()
{
int n; while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
{
int num;
scanf("%d",&num);
for(int j=1;j<=num;j++)
{
int a;
scanf("%d",&a); //i/32代表该集合在那个整数里面
int bit=1<<(i%32); //i%32代表该集合在该整数中的第几位 位置
//if((sa[a][i/32]&bit)==0) //之前没有出现,因为一个集合可能有多个相同的数
sa[a][i/32]|=bit;
}
}
int q;
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
int a,b;
scanf("%d%d",&a,&b);
bool flag=false;
for(int i=0;i<32;i++)
if(sa[a][i]&sa[b][i])
{
flag=true;
break;
}
if(flag)
printf("Yes\n");
else
printf("No\n");
}
}
return 0;
}
解法二:
用STL里面的bitset来做。
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1 #pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; bitset<1100>myb[11000],temp; int main()
{
int n; while(~scanf("%d",&n))
{
for(int i=1;i<=10000;i++)
myb[i].reset(); //清0
for(int i=0;i<n;i++)
{
int num;
scanf("%d",&num);
for(int j=1;j<=num;j++)
{
int a;
scanf("%d",&a);
myb[a].set(i); //置1
}
}
int q;
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
int a,b;
scanf("%d%d",&a,&b);
temp=myb[a]&myb[b];
if(temp.any()) //是否存在1
printf("Yes\n");
else
printf("No\n");
}
}
return 0;
}
压位加速-poj-2443-Set Operation的更多相关文章
- POJ 2443 Set Operation(压位加速)
http://poj.org/problem?id=2443 题意: 有1000个集合,每个集合有至多10000个数,之后输入多个询问,判断询问的两个数是否位于同一个集合. 思路: 位运算...很强大 ...
- POJ 2443 Set Operation (按位压缩)
Description You are given N sets, the i-th set (represent by S(i)) have C(i) element (Here "set ...
- [POJ 2443] Set Operation (bitset)
题目链接:http://poj.org/problem?id=2443 题目大意:给你N个集合,每个集合里有若干个数.M个查询,每个查询有a,b两个数.问是否存在一个集合同时包含a,b这两个数.若存在 ...
- POJ 2443 Set Operation
Set Operation Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 3558 Accepted: 1479 Des ...
- POJ 2443 Set Operation 题解
本文同时发布于 博客园 洛谷博客 题目链接 题目分析 给你n个集合,每个集合里面都有可能会重复的数字 q个询问,每次询问两个数是否会在同一集合内 $n<=1000$ $q<=200000$ ...
- [hdu5340]二分,枚举,二进制压位加速
题意:判断一个字符串能否划成三段非空回文串. 思路:先用二分+hash在nlogn的时间内求出以每条对称轴为中心的回文串的最大半径r[i](可以用对称的两个下标之和来表示 ),然后利用r[i]求出pr ...
- [BZOJ5109][LOJ #6252][P4061][CodePlus 2017 11月赛]大吉大利,今晚吃鸡!(最短路+拓扑排序+传递闭包+map+bitset(hash+压位))
5109: [CodePlus 2017]大吉大利,晚上吃鸡! Time Limit: 30 Sec Memory Limit: 1024 MBSubmit: 107 Solved: 57[Sub ...
- codevs 3119 高精度练习之大整数开根 (各种高精+压位)
/* codevs 3119 高精度练习之大整数开根 (各种高精+压位) 二分答案 然后高精判重 打了一个多小时..... 最后还超时了...压位就好了 测试点#1.in 结果:AC 内存使用量: 2 ...
- UOJ #314. 【NOI2017】整数 | 线段树 压位
题目链接 UOJ 134 题解 可爱的电音之王松松松出的题--好妙啊. 首先想一个朴素的做法! 把当前的整数的二进制当作01序列用线段树维护一下(序列的第i位就是整数中位权为\(2^k\)的那一位). ...
随机推荐
- C++中虚函数的作用是什么?它应该怎么用呢?(转)
虚函数联系到多态,多态联系到继承.所以本文中都是在继承层次上做文章.没了继承,什么都没得谈. 下面是对C++的虚函数这玩意儿的理解. 一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你 ...
- sqlserver,执行生成脚本时“引发类型为“System.OutOfMemoryException”的异常”(已解决)
sqlserver,执行生成脚本时“引发类型为“System.OutOfMemoryException”的异常”(已解决) 出现此错误主要是因为.sql的脚本文件过大(一般都超过100M)造成内存无法 ...
- hdu 1042
貌似之前也写过这个题目的解题报告...老了,记性不好 从贴一遍吧! 代码理解很容易 AC代码: #include <iostream> #include <stdio.h> # ...
- 转载——SQL Server中Rowcount与@@Rowcount的用法
转载自:http://www.lmwlove.com/ac/ID943 rowcount的用法: rowcount的作用就是用来限定后面的sql在返回指定的行数之后便停止处理,比如下面的示例, set ...
- 在MVC中利用uploadify插件实现上传文件的功能
趁着近段的空闲时间,开发任务不是很重,就一直想把以前在仓促时间里所写的多文件上传功能改一下,在网上找了很多例子,觉得uploadify还可以,就想用它来试试.实现自己想要的功能.根据官网的开发文档,同 ...
- JavaWeb学习笔记之Servlet(一)
1. 引子: 当我们开始进入JavaWeb开发的学习时,我们就必须要和Servlet和HTTP这两个词进行打交道了,尤其是Servlet.即使到了后面使用JSP (我们知道JSP其本身就是一个Serv ...
- 关于R文件丢失的一个问题
android studio在编辑布局文件时,一般为了省事,如TextView控件中的text属性这样写 android:text="<500",编译不会报错,但是运行时会出 ...
- EasyUi DataGrid中数据编辑方式及编辑后数据获取,校验处理
EasyUi中的DataGrid提供前台编辑的相关函数. 实现客户选中DataGrid中一列后,对选中列中的一个字段进行编辑,并对数据进行实时校验后,传递至后台保存的需求, 主要涉及到DataGrid ...
- dede后台反应特别慢-转
找到织梦后台管理目录下的/templets/index_body.htm文件 将第25行至第35行部分js代码注释掉. 就这么简单
- CommandBehavior.CloseConnection的使用
CommandBehavior.CloseConnection的使用 分析问题 由于流模式读取数据库的特点,在具体应用时很难确定数据库连接何时才能被关闭,因为读取的动作是连续进行的,下面是一个常见的数 ...