题目链接:https://codeforces.com/contest/1689/problem/E
解题思路:
根据位运算可以简单的推算出,其实至多只需要2次操作就可以了。也就是操作最小bit位最大的那个,极端情况下需要对两个最小bit位最大的进行操作,一个+1,一个-1。
- #include
- using namespace std;
- #define lson l, mid, rt<<1
- #define rson mid+1, r, rt<<1|1
- typedef long long ll;
- typedef unsigned long long ull;
- const int mx = 2e3 + 10;
- const int mod = 998244353;
- typedef pair <int, int> Pa;
-
- int a[mx];
- int fa[mx];
- set <int> st, vec[30], val[mx];
- map <int, int> mp;
- int ans;
-
- int findfa(int x) {
- return x == fa[x]? x : fa[x] = findfa(fa[x]);
- }
-
- int cal(int n)
- {
- st.clear();
- for (int i=1;i<=n;i++)
- fa[i] = i;
- for (int i=0; i<30; i++) {
- if (vec[i].size() > 1) {
- auto it1 = vec[i].begin();
- auto it2 = it1;
- it2++;
- while (it2 != vec[i].end()) {
- int fu = findfa(*it1);
- int fv = findfa(*it2);
- fa[fv] = fu;
- it2++, it1++;
- }
- }
- }
- for (int i=1;i<=n;i++) {
- int fu = findfa(i);
- st.insert(fu);
- }
- return st.size();
- }
-
- void print(int n)
- {
- printf("%d\n", ans);
- for (int i=1;i<=n;i++)
- printf("%d%c", a[i], i==n?'\n':' ');
- }
-
- int main()
- {
- for (int i=0;i<30;i++)
- mp[1<
- int t;
- scanf("%d", &t);
- while (t--) {
- int n;
- scanf("%d", &n);
- for (int i=0;i<30;i++)
- vec[i].clear();
- ans = 0;
- for (int i=1;i<=n;i++) {
- val[i].clear();
- fa[i] = i;
- scanf("%d", a+i);
- if (a[i] == 0)
- ans++, a[i]++;
- for (int j=0; (1<
- if ((1<
- vec[j].insert(i);
- val[i].insert(j);
- }
- }
- }
- if (cal(n) == 1) {
- print(n);
- continue;
- }
-
- for (int i=1;i<=n;i++) {
- if (a[i] != 1) {
- int bit_val = a[i] - (a[i] & (a[i] - 1));
- int bit_pos = mp[bit_val];
- a[i]--;
- vec[bit_pos].erase(i);
- for (int j=0;j
- vec[j].insert(i);
- //printf("########### %d %d\n", i, bit_pos);
- if (cal(n) == 1) {
- ans++;
- print(n);
- break;
- }
- a[i]++;
- vec[bit_pos].insert(i);
- for (int j=0;j
- vec[j].erase(i);
- }
- for (int v: val[i])
- vec[v].erase(i);
- set <int> temp_st;
- a[i]++;
- for (int j=0; (1<
- if ((1<
- vec[j].insert(i);
- temp_st.insert(j);
- }
- }
- if (cal(n) == 1) {
- ans++;
- print(n);
- break;
- }
- a[i]--;
- for (int v: temp_st)
- vec[v].erase(i);
- for (int v: val[i])
- vec[v].insert(i);
- }
- if (st.size() != 1) {
- int max_val = 0, pos;
- for (int i=1;i<=n;i++) {
- int bit_val = a[i] - (a[i] & (a[i] - 1));
- if (bit_val > max_val) {
- max_val = bit_val;
- pos = i;
- }
- }
- a[pos]--;
- for (int i=1;i<=n;i++) {
- if (a[i] & max_val) {
- a[i]++;
- break;
- }
- }
- ans += 2;
- print(n);
- }
-
- }
- return 0;
- }
- // 8
- // 8
- // 4 4 8 8 16 16 32 32
-
相关阅读:
Maven 常用镜像站地址
[极客大挑战 2019]HardSQL-1
【论文笔记】SDCL: Self-Distillation Contrastive Learning for Chinese Spell Checking
【数据结构】单链表——单链表的定义及基本操作的实现(头插、尾插、头删、尾删、任意位置的插入与删除)
单点故障解决方案之Smart Link与Monitor Link
前端重新部署通知用户刷新
一文掌握CodiMD安装与使用
【JAVA基础】数组详解
C++ auto用法示例
安科瑞ADL400产品功能及参数说明,适用于5G基站计量使用
-
原文地址:https://blog.csdn.net/a1214034447/article/details/126409412