一本通OJ-lowbit 求和

lowbit 求和

题意

lowbit(x[i] xor x[j])

分析

显然暴力会超时。那么我们考虑另外做法。

显然lowbit(x xor y)我们关心的是x,y在二进制条件下从最后一位开始谁先出现1。因而我们考虑先把所有位置的数倒序插入进Trie树中,而后我们记录下每个节点p的出现次数num[i]。而后我们对于每一个数,每一位进行枚举,若不同我们考虑贡献为num[i](1<<dep),那么怎么统计呢?我们考虑每次走到分叉口怎样统计不一样的,那么显然有res+=num[tr[p][chxor1](1<<dep)]相加即可。xor01

代码

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

const int N=1e5+7;
int n,a[N];
const int mod=199907210507;
int tr[N*60][3];
int tot=1,num[N*60];
int ans;
void insert(int id){
    int p=1;
    for(int i=0;i<=61;i++){
        int ch=(a[id]>>i)&1;
        if(!tr[p][ch]) tr[p][ch]=++tot;
        p=tr[p][ch];
        num[p]++;
    }
}
int get_lowbit_ans(int id){
    int p=1;
    int res=0;
    for(int i=0;i<=61;i++){
        int ch=(a[id]>>i)&1;
        res+=num[tr[p][ch^1]]%mod*(1ll<<i)%mod;
        p=tr[p][ch];
    }
    return res;
}
void solve(){
    for(int i=1;i<=n;i++){ans%=mod;ans+=get_lowbit_ans(i);}
    printf("%lld",ans);
}
signed main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]),insert(i);
    solve();
    return 0;
}
posted @   Zimo_666  阅读(29)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示