2021牛客暑期多校训练营7(补题)

博客围绕两道算法题展开。一是已知两个正整数x、s满足x∣y=s,求正整数y的个数,可通过二进制与运算求解;二是给定n长序列,求满足ai∗aj=ak的情况数,用数组表示数的出现次数计算。还分享了解题中的失误与卡点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

I、xay loves or

题目链接:xay loves or

题目大意:给你两个正整数 x 、 s x、s xs,并且满足关系 x ∣ y = s x|y=s xy=s,求满足条件的正整数 y y y的个数。

题目思路:我们可以由 ∣ ( 或 ) |(或) 的性质知道,我们先把 x 、 y 、 s x、y、s xys三个数看成二进制表示,我们可以知道对于 s s s某一位 0 0 0的情况, x x x y y y这个地方也应该为零,那么 y y y唯一可以选择的就是当 s s s这位是 1 1 1而且 x x x的同一位也为 1 1 1的时候我们就可以由两个不同的选择,通俗讲,就是把 x x x s s s进行一次与运算,统计其结果二进制中的 1 1 1个数为 k k k,则答案就是 2 k 2^k 2k个,不过当答案包括零的时候需要减去这个情况。

吐槽:因为没有注意计算出的是否包括 0 0 0,我就直接减去了 1 1 1,然后我就 W A WA WA接近整整半个小时。

代码:

#include <iostream>
using namespace std;

long long get(long long n)
{
	long long temp, cnt = 0;
	while(n != 0)
	{
		temp = n & 1;
		if (temp == 1) cnt ++;
		n = n >> 1;
	}
	return cnt;
} 

long long qpow(long long a, long long b)
{
	long long res = 1;
	while(b > 0)
	{
		if (b & 1) res = res * a;
		a = a * a;;
		b = b >> 1;
	}
	return res;
}

int main ()
{
	long long x, s;
	cin >> x >> s;
	long long y = x & s;
	if (y != x) 
	{
		cout << 0 << endl;
		return 0;
	}
	long long z = x ^ s;
	long long k = get(x);
	long long ans = qpow(2,k);
	if (z == 0) ans--;
	cout << ans << endl;
	return 0;
}

H、xay loves count

题目连接:xay loves count

题目大意:给你一个 n n n长的序列, a i , a j , a k a_i,a_j,a_k ai,aj,ak都是来自序列,请问序列中包括多少种情况满足 a i ∗ a j = a k a_i * a_j = a_k aiaj=ak

题目思路:用一个数组表示 1 1 1 1000000 1000000 1000000中每个数的出现次数,直接计算 ∑ i = 1 n ∑ j = 1 1000000 i a i ∗ a j ∗ a i ∗ j \sum_{i=1}^{n} \sum_{j=1}^{\frac{1000000}{i}}{a_i*a_j*a_{i*j}} i=1nj=1i1000000aiajaij就是答案。

吐槽:这题我卡到比赛结束也没有做出来,确实,没有写到这么简便,但是思维差不多,都是从前往后推。代码很短。

代码:

#include <iostream>
using namespace std;
long long n, a[1000010];
int main ()
{
	cin >> n;
	for(int i = 1; i <= n; i++)
	{
		int x;
		cin >> x;
		a[x] ++;
	}
	
	long long cnt = 0;
	for(int i = 1; i <= 1000005; i++)
	{
		for(int j = 1; j*i <= 1000005; j++)
		{
			cnt += a[i] * a[j] * a[i*j];
		}
	}
	
	cout << cnt << endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值