AcWing 第102场周赛 题解

第一次ak周赛,写篇题解纪念一下

第一题

给定两个长度为 n n n 的整数序列 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an 以及 b 1 , b 2 , … , b n b_1,b_2,…,b_n b1,b2,,bn

A = a 1  or  a 2  or  …  or  a n A = a_1\ \text{or}\ a_2\ \text{or}\ …\ \text{or}\ a_n A=a1 or a2 or  or an
B = b 1 or  b 2  or  …  or  b n B = b_1 \text{or}\ b_2\ \text{or}\ …\ \text{or}\ b_n B=b1or b2 or  or bn

请你计算并输出 A + B A+B A+B 的值。

or \text{or} or 表示按位或运算。

输入格式

第一行包含整数 n n n

第二行包含 n n n 个整数 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an

第三行包含 n n n 个整数 b 1 , b 2 , … , b n b_1,b_2,…,b_n b1,b2,,bn

输出格式

一个整数,表示 A + B A+B A+B 的值。

数据范围

3 3 3 个测试点满足 1 ≤ n ≤ 10 1 \le n \le 10 1n10
所有测试点满足 1 ≤ n ≤ 1000 1 \le n \le 1000 1n1000 0 ≤ a i , b i ≤ 1 0 9 0 \le a_i,b_i \le 10^9 0ai,bi109

输入样例1:
5
1 2 4 3 2
2 3 3 12 1
输出样例1:
22
输入样例2:
10
13 2 7 11 8 4 9 8 5 1
5 7 18 9 2 3 0 11 8 6
输出样例2:
46
思路

签到题,直接模拟即可。
代码:

#include <bits/stdc++.h>

using namespace std;

const int N = 1010;

long long a[N], b[N];

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++ i ) cin >> a[i];
    for (int i = 1; i <= n; ++ i ) cin >> b[i];
    long long A = a[1], B = b[1];
    for (int i = 2; i <= n; ++ i ) {
        A |= a[i], B |= b[i];
    }
    
    cout << A + B << '\n';
    
    return 0;
}

第二题

给定一个长度为 n n n 的整数序列 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an

你可以对该序列进行任意次倍增操作(也可以不进行任何操作)。

每次倍增操作可以任选序列中的一个元素,并将其乘以 2 2 2 或乘以 3 3 3

我们的目标是让序列中所有元素的值都相等。

请你判断,目标是否能够实现。

输入格式

第一行包含整数 n n n

第二行包含 n n n 个整数 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an

输出格式

如果可以让序列中所有元素的值都相等,则输出 Yes,否则,输出 No

数据范围

6 6 6 个测试点满足 2 ≤ n ≤ 10 2 \le n \le 10 2n10
所有测试点满足 2 ≤ n ≤ 1 0 5 2 \le n \le 10^5 2n105 1 ≤ a i ≤ 1 0 9 1 \le a_i \le 10^9 1ai109

输入样例1:
4
75 150 75 50
输出样例1:
Yes
输入样例2:
3
100 150 250
输出样例2:
No
思路

我们可以将每个数的2和3的因子都除掉,再判断是否全部相等就可以了,很水的一道数论题。
代码:

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

int n;
int a[N];

bool judge() {
	for (int i = 1; i <= n; ++ i ) {
		while (a[i] % 2 == 0) a[i] /= 2;
		while (a[i] % 3 == 0) a[i] /= 3;
		//  把所有数的2和3的因数除掉
	}
	
	for (int i = 2; i <= n; ++ i ) 
		if (a[i] != a[i - 1]) //    每次比较相邻两个
			return false;
	
	return true;
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; ++ i ) scanf("%d", &a[i]);
	
	if (judge()) puts("Yes");
	else puts("No");
	
	return 0;
}

第三题

给定一个长度为 n n n 的整数序列 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an 和一个整数 k k k

请你计算有多少个三元组 ( x , y , z ) (x,y,z) (x,y,z) 同时满足以下所有条件:

  1. 1 ≤ x < y < z ≤ n 1 \le x < y < z \le n 1x<y<zn
  2. a x × k = a y a_x \times k = a_y ax×k=ay
  3. a y × k = a z a_y \times k = a_z ay×k=az
输入格式

第一行包含两个整数 n , k n,k n,k

第二行包含 n n n 个整数 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an

输出格式

一个整数,表示满足所有条件的三元组的数量。

数据范围

6 6 6 个测试点满足 1 ≤ n ≤ 10 1 \le n \le 10 1n10
所有测试点满足 1 ≤ n , k ≤ 2 × 1 0 5 1 \le n,k \le 2 \times 10^5 1n,k2×105 − 1 0 9 ≤ a i ≤ 1 0 9 -10^9 \le a_i \le 10^9 109ai109

输入样例1:
5 2
1 1 2 2 4
输出样例1:
4
输入样例2:
3 1
1 1 1
输出样例2:
1
输入样例3:
10 3
1 2 6 2 3 6 9 18 3 9
输出样例3:
6
思路

我们拿两个哈希表,分别记录数列中每个数的出现个数与满足条件的y的个数,如果当前枚举到的x合法,就累加答案;最后输出答案。
注意:本题的 a i a_i ai范围很大,需要开long long
代码:

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 2 * 1e5 + 10;

int n, k;
int a[N];

signed main() {
	scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; ++ i ) cin >> a[i];
	
	unordered_map<int, int> cntn, cntx;
	int res = 0;
	
	for (int i = 1; i <= n; ++ i ) {
		if (cntx.count(a[i])) res += cntx[a[i]];
		if (cntn.count(a[i])) cntx[a[i] * k] += cntn[a[i]];
		++ cntn[a[i] * k] ;
	}
	
	cout << res << '\n';
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>