A. Array Elimination

目录

1.Problem

2.Input

3.Output

4.Examples

4.1input

4.2output

5.Code

6.Conclusion


1.Problem

You are given array a1,a2,…,ana1,a2,…,an, consisting of non-negative integers.

Let's define operation of "elimination" with integer parameter kk (1≤k≤n1≤k≤n) as follows:

  • Choose kk distinct array indices 1≤i1<i2<…<ik≤n1≤i1<i2<…<ik≤n.
  • Calculate x=ai1 & ai2 & … & aikx=ai1 & ai2 & … & aik, where && denotes the bitwise AND operation (notes section contains formal definition).
  • Subtract xx from each of ai1,ai2,…,aikai1,ai2,…,aik; all other elements remain untouched.

Find all possible values of kk, such that it's possible to make all elements of array aa equal to 00 using a finite number of elimination operations with parameter kk. It can be proven that exists at least one possible kk for any array aa.

Note that you firstly choose kk and only after that perform elimination operations with value kk you've chosen initially.

2.Input

Each test contains multiple test cases. The first line contains the number of test cases tt (1≤t≤1041≤t≤104). Description of the test cases follows.

The first line of each test case contains one integer nn (1≤n≤2000001≤n≤200000) — the length of array aa.

The second line of each test case contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai<2300≤ai<230) — array aa itself.

It's guaranteed that the sum of nn over all test cases doesn't exceed 200000200000.

3.Output

For each test case, print all values kk, such that it's possible to make all elements of aa equal to 00 in a finite number of elimination operations with the given parameter kk.

4.Examples

4.1input

5
4
4 4 4 4
4
13 7 25 19
6
3 5 3 1 7 1
1
1
5
0 0 0 0 0

4.2output

1 2 4
1 2
1
1
1 2 3 4 5

5.Code

#include <iostream>
#include <cstdio>
#include <vector>
#include <utility>

using namespace std;

const int MAX_N = 100005;

int n;
int cnt[30];

int readint() {
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

int countSetBits(int num) {
    int count = 0;
    while (num > 0) {
        count += (num & 1);
        num >>= 1;
    }
    return count;
}

void solve() {
    int T = readint();
    while (T--) {
        n = readint();
        for (int j = 0; j < 30; j++)
            cnt[j] = 0;
        
        int x;
        for (int i = 1; i <= n; i++) {
            x = readint();
            for (int j = 0; j < 30; j++) {
                cnt[j] += (x & (1 << j)) ? 1 : 0;
            }
        }

        for (int i = 1; i <= n; i++) {
            int fl = 0;
            for (int j = 0; j < 30; j++) {
                if (cnt[j] % i) {
                    fl = 1;
                    break;
                }
            }
            if (!fl) {
                printf("%d ", i);
            }
        }
        printf("\n");
    }
}

int main() {
    solve();
    return 0;
}

6.Conclusion

        这段C++代码的主要作用是解决一个问题,其问题的描述和解决方法如下:

1.代码首先包含了一些必要的头文件,如iostream、cstdio、vector等。
2.定义了一个常量MAX_N,其值为100005。
3.声明了一些全局变量,包括整数n和一个整数数组cnt,数组cnt的长度为30。
4.定义了一个函数readint(),用于从标准输入中读取一个整数,并将其返回。
5.定义了一个函数countSetBits(int num),用于计算一个整数的二进制表示中1的个数。
6.定义了一个函数solve(),用于解决问题的核心逻辑。在函数内部,首先读取一个整数T,表示要解决的测试用例的数量。
7.然后,进入一个循环,每次循环处理一个测试用例。在每个测试用例中,首先读取一个整数n,表示数组的长度。
8.接下来,初始化数组cnt的所有元素为0。
9.通过循环,读取n个整数,并对这些整数进行处理。对于每个整数x,它的二进制表示中的每一位被分别检查,然后更新数组cnt的对应位置,以记录在当前测试用例中,该位上出现1的次数。
10.随后,再次通过循环,对每个数i进行检查,以确定是否满足特定条件。具体地说,对于每个i,它的二进制表示中的每一位都与数组cnt对应位置上的值取余。如果所有位都满足取余为0的条件,那么就输出i,表示i是符合条件的数。
11.最后,输出换行符,结束当前测试用例的处理。
12.在主函数main()中,调用solve()函数来执行整个程序的逻辑。

        总的来说,这段代码的作用是解决多个测试用例,每个测试用例中有一个整数数组,然后对每个测试用例中的整数进行位运算和数学运算,找出符合特定条件的整数,并输出这些整数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向阳而生__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值