2017 Multi-University Training Contest - Team 5:1001. Rikka with Candies(手写bitset)




题意:

给你两个数组A,B,数组中每个数字范围在[1, 50000]内且不重复,q次询问,每次一个值x,问有多少对(a, b),满足

a%b==x,a∈A,b∈B


实际上这题正解还是n²的暴力

思路很简单,询问直接预处理,枚举每个价格,再枚举价格的倍数

具体题解:http://bestcoder.hdu.edu.cn/blog/2017-multi-university-training-contest-5


只不过因为每个价格只会出现1次,最后答案又是对2取模

所以整个过程只有数字0和1出现,这样的话你一个int型就可以保存32个数据了,而不是保存一个整型

整体复杂度就降为(n²/32),居然就可以过


因为bieset操作受限,没法将一个区间提出来

假设枚举到价格x,倍数i,很显然A数组[x*i, x*i+x-1]这个区间对答案区间[0, x-1]有贡献)

所以要手写bitset

第一次写感觉挺提麻烦的,具体看程序

#include<stdio.h>
#include<string.h>
#include<bitset>
#include<algorithm>
using namespace std;
bitset<50005> pri;
unsigned int buy[1605], ans[1605];
int main(void)
{
	int T, n, m, k, i, j, q, x, now, temp, num;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d%d%d", &n, &m, &q);
		memset(ans, 0, sizeof(ans));
		memset(buy, 0, sizeof(buy));
		pri.reset();
		for(i=1;i<=n;i++)
		{
			scanf("%d", &x);
			buy[x/32] |= 1<<(x%32);
		}
		for(i=1;i<=m;i++)
		{
			scanf("%d", &x);
			pri[x] = 1;
		}
		for(i=1;i<=50000;i++)
		{
			if(pri[i]==0)
				continue;
			for(j=0;j<=50000;j+=i)
			{
				now = j, temp = min(j+i-1, 50000);
				for(k=0;k<=(temp-j)/32-1;k++)			//一般来讲都是ans[k]加上buy[now]的后半部分以及buy[now+1]的前半部分
				{
					ans[k] ^= buy[now/32]>>(now%32);					//buy[now]的后半部分往前移动和ans[k]异或
					now += 32;
					ans[k] ^= (buy[now/32]&((1<<now%32)-1))<<(32-now%32);		//buy[now+1]的左半部分往后移动和ans[k]异或
				}
				for(num=now;now<=temp;now++)
				{
					if(buy[now/32]&(1<<(now%32)))					//最后一点直接暴力,每一位单独异或上去
						ans[k] ^= (1<<(now-num));
				}
			}
		}
		while(q--)
		{
			scanf("%d", &x);
			if(ans[x/32]&(1<<(x%32)))
				printf("1\n");
			else
				printf("0\n");
		}
	}
	return 0;
}
/*
1
10 10 10
1 18 22 26 38 42 59 64 77 108
3 4 8 16 24 38 54 56 57 76
0 1 5 8 15 23 32 44 45 48
*/
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值