训练实录 | 2021牛客暑期多校训练营7

2021牛客暑期多校训练营7

传送门

H - xay loves count

solved by YukiSam. 03:55:59(-4)

题意: 给定n,再给出n个数字的序列,现需要找到三元组(i,j,k)使得 a i ∗ a j = a k a_{i}*a_{j}=a_{k} aiaj=ak,求问有几组解。(i,j,k可以存在相等关系)

思路: 在输入的时候同时拿数组 t t t 存每个值出现次数,套两个for循环枚举(为了剪枝,第二个循环条件可以设为i*j<=maxn),可以推出答案的公式 a n s = t [ i ] ∗ t [ j ] ∗ t [ i ∗ j ] ans=t[ i ]*t[ j ]*t[ i*j ] ans=t[i]t[j]t[ij] .等式右边如果三项中任意一项不存在(即次数为零),对答案不影响,如果三项都不为零就说明存在,那么通过排列组合得到 C t [ i ] 1 ∗ C t [ j ] 1 ∗ C t [ i ∗ j ] 1 = t [ i ] ∗ t [ j ] ∗ t [ i ∗ j ] C_{t[ i ]}^1*C_{t[ j ]}^1*C_{t[ i*j ]}^1=t[ i ]*t[ j ]*t[ i*j ] Ct[i]1Ct[j]1Ct[ij]1=t[i]t[j]t[ij]

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=100000;
int n,x;
ll t[maxn];
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%d",&x);
		t[x]++;
	}
	ll ans=0;
	for(int i=1;i<maxn;i++)
		for(int j=1;j*i<maxn;j++)
			ans+=t[i]*t[j]*t[i*j];
	printf("%lld",ans);
}

I - xay loves or

solved by Micky. 00:33:02(-3)

题意:
给出正整数x和正整数s,求出有多少个正整数y,满足x|y=s。

思路:
考虑x与s上的二进制位,设xi是x的二进制第i位,si是s的二进制第i位。
如果xi=1,si=1,那么yi可以取1或0,ans*=2.
如果xi=0,si=0或xi=0,si=1,yi可以取1,ans*=1。
如果xi=1,si=0,不存在yi,ans直接等0.
(注意y为正整数,如果x|0=s,ans–,因此wa了几发)

/**/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <iomanip>
#pragma warning (disable:4996)

typedef long long LL;
using namespace std;

const long long mod = 1e9 + 7, maxn = 1e6 + 9;
const double eps = 1e-10;
string a, b;
int cnt[maxn];
int bitx[33], bits[33];

int main()
{	
	long long x, y, s;
	memset(bitx, 0, sizeof(bitx));
	memset(bits, 0, sizeof(bits));
	cin >> x >> s;
	long long xx = x, ss = s;
	int numx = 0, nums = 0;
	while (x) {
		bitx[numx++] = x % 2;
		x /= 2;
	}
	while (s) {
		bits[nums++] = s % 2;
		s /= 2;
	}
	long long flag = 0, ans = 1;
	for (int i = 0; i < 33; i++) {
		if (bitx[i] == 1 && bits[i] == 1)ans *= 2;
		if (bitx[i] == 1 && bits[i] == 0) {
			ans *= 0;
			break;
		}
	}
	if ((xx | 0) == ss && ans != 0)ans--;
	cout << ans << endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值