两序列_序对和的异或(考虑位权)

本文分享了AtCoder平台上一道竞赛题目的解题思路及代码实现。通过枚举和二分查找技术,解决了大规模数据集上的对数和异或运算问题,时间复杂度达到O(28*n*logn)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

problem

https://arc092.contest.atcoder.jp/tasks/arc092_b

题意

给你两个序列a,b 各n个数

共n^2对数 求这些对的和 之间异或的值

n 200000

a,b里数1<<28

思路

对于最后的结果

考虑每一位 pair的贡献 发现 对于一个a[i] , a[i]+b[j]对于当前位的影响是有规律的 即使其为1的区间为:

a[i]+b[j] ∈ [v,2v) [ v , 2 v ) [3v,n) [ 3 v , n ) 而更高位对当前位永远不会影响

对于每一位 枚举a 二分b求解两个范围的边界即可

时间复杂度 O(28nlogn) O ( 28 ∗ n ∗ l o g n )

代码示例

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

const int maxn=2e5+10;
int a[maxn];
int b[maxn];

int n;

int main()
{
    //ios::sync_with_stdio(false);
    //freopen("in.txt","r",stdin);
    scanf("%d",&n);
    for(int i=0;i<n;++i) scanf("%d",&a[i]);
    for(int i=0;i<n;++i) scanf("%d",&b[i]);
    int ans=0;
    for(int v=(1<<28);v;v>>=1){
        int tp=0;
        for(int i=0;i<n;++i){
            a[i]&=((v<<1)-1);
            b[i]&=((v<<1)-1);
        }
        sort(a,a+n);
        sort(b,b+n);
        for(int i=n-1;i>=0;--i){//枚举a
            int v1=lower_bound(b,b+n,v-a[i])-b;
            int v2=lower_bound(b,b+n,2*v-a[i])-b;
            int v3=lower_bound(b,b+n,3*v-a[i])-b;
//            while(j<n && a[i]+b[j]<v) j++;
//            while(k<n && a[i]+b[k]<2*v) k++;
//            while(l<n && a[i]+b[l]<3*v) l++;
            tp+=v2-v1+n-v3;
            tp&=1;
        }
        if(tp) ans|=v;
    }
    printf("%d\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值