ARC127D Sum of Min of Xor

ARC127D Sum of Min of Xor

性质分析加通用套路。

思路

首先我们把这题的 min 给去掉,那么我们按位算贡献,可以求出和。这是这种式子的通用套路。

考虑加上 min,那么我们先按照 (ai,bi) 的最高位分为:(1,0)(0,1)(1,1)(0,0) 四种情况。

可以发现用贡献的组如下:

  • (0,0)(0,1) 贡献为 aiaj
  • (0,0)(1,0) 贡献为 bibj。​
  • (1,1)(1,0) 贡献为 aiaj
  • (1,1)(0,1) 贡献为 bibj。​
  • (1,1)(1,1)​ 贡献需要向下枚举一位计算。
  • (0,0)(0,0) 贡献需要向下枚举一位计算。

那么已知贡献的我们可以用通用套路算,不知道的向下枚举即可。

CODE

#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define K 18

const int maxn=3e5+5;

int n;
int a[maxn],b[maxn];

ll ans;

vector<int>sd;

void C(vector<int> &d1,vector<int> &d2,bool w)
{
    for(int i=0;i<K;i++)
    {
        int c1,c2;
        c1=c2=0;
        for(int j:d1) c1+=(w?b[j]:a[j])>>i&1;
        for(int j:d2) c2+=(w?b[j]:a[j])>>i&1;
        ans+=(1ll*c1*(d2.size()-c2)+1ll*c2*(d1.size()-c1))<<i;
    }
}
void S(int p,vector<int> &d)
{
    if(d.empty()) return ;
    if(p==-1)
    {
        for(int i=0;i<K;i++)
        {
            int c1=0;
            for(int j:d)
                c1+=a[j]>>i&1;
            ans+=1ll*c1*(d.size()-c1)<<i;
        }
        return ;
    }
    vector<int> l[2][2];
    for(int i:d) l[a[i]>>p&1][b[i]>>p&1].push_back(i);
    C(l[0][0],l[0][1],0);
    C(l[0][0],l[1][0],1);
    C(l[1][1],l[0][1],1);
    C(l[1][1],l[1][0],0);
    for(int i:l[0][0]) l[1][1].push_back(i);
    for(int i:l[0][1]) l[1][0].push_back(i);
    S(p-1,l[1][1]),S(p-1,l[1][0]);
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),sd.push_back(i);
    for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    S(K-1,sd);
    printf("%lld",ans);
}
posted @   彬彬冰激凌  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示