Codeforces #672 Div2 1420B. Rock and Lever

这篇博客介绍了一种解决数组中满足特定条件的数对数量问题的方法。通过分析题目,博主发现当两个数的最高位为1并且相同的时候,它们的与和异或操作可以满足条件。通过计算每个最高位1出现的次数,博主利用等差数列公式求解,给出了AC代码。代码简洁高效,展示了位运算在算法中的应用。
摘要由CSDN通过智能技术生成

题目链接

1420B

题解

题意

找到数组中满足 i < j i<j i<j ( a i (a_i (ai & a j ) a_j) aj) ≤ ( a i ⨁ a j ) \leq (a_i \bigoplus a_j) (aiaj)pair的数量。

思路

a i a_i ai a j a_j aj的二进制表示的最高位位置相同且为1时,可以满足上述条件。

  1. 最高位的1相与之后得到1
  2. 最高位的1异或之后得到0(异或可以看作不进位的加法)。

求数量可以在观察之后可以得出等差数列的做法。

AC代码

#include <bits/stdc++.h>

using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(A, tree) memcpy(A, tree, sizeof(tree))
#define eps (1e-8)
#define PI (acos(-1.0))
#define INF (0x3f3f3f3f)
#define mod (ll)(1e9+7)
typedef pair<int, int> P;

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        map<ll, int> mp;
        rep(i, 1, n) {
            ll t;
            cin >> t;
            int cnt = 0;
            for (int i = 1; i <= 30; i++) {
                if (t >> 1) cnt = i;
                t >>= 1;
                if (t == 0) break;
            }
            mp[cnt] += 1;
        }
        ll ans = 0;
        for (auto it : mp) {
            ll tmp = it.second;
            if (tmp >= 2) {
                if (tmp & 1) ans += (tmp - 1) / 2 * tmp;
                else ans += (tmp) / 2 * (tmp - 1);
            }
        }
        cout << ans << endl;
    }
    return 0;
}

之后的代码

看完大佬的代码之后我悟了!

#include <bits/stdc++.h>

using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(A, tree) memcpy(A, tree, sizeof(tree))
#define eps (1e-8)
#define PI (acos(-1.0))
#define INF (0x3f3f3f3f)
#define mod (ll)(1e9+7)
typedef pair<int, int> P;

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    int n, x;
    int t[40];
    ll ans = 0;
    for (cin >> n; cin >> n; cout << ans << ' ') {
        ans = 0;
        rep(i, 0, 30) t[i] = 0;
        rep(i, 1, n) {
            cin >> x;
            for (int i = 30; i >= 0; i--) if (x & (1 << i)) {t[i] += 1; break;}
        }
        rep(i, 0, 30) if (t[i] >= 2) ans += 1LL * (t[i] - 1) * t[i] / 2LL;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值