Loading

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;
}
posted @ 2023-05-06 22:03  popcoount  阅读(11)  评论(0编辑  收藏  举报  来源