• hdu 5269 ZYB loves Xor I 分治 || Trie


    题目大意:

    长度为(n)的数组A。求对于所有数对((i,j)(i in [1,n],j in [1,n]))(lowbit(A_i xor A_j))之和.答案对998244353取模
    定义lowbit(0)=0

    题解:

    官方题解给出的Trie的做法...

    但是我有一个分治的做法:
    我们从低到高枚举二进制位:
    在每个二进制位枚举时,将所有的数按照这一二进制位为0或为1分成两组
    这样一共有两组的siz的乘积对的数在这一位上对答案做出贡献
    由于我们发现以后这两组数间不可能存在一组数再次对答案做出贡献
    所以我们可以直接将问题划分成两个不相干的子问题,递归求解.
    也是(O(nloga_i))

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    inline void read(int &x){
    	x=0;char ch;bool flag = false;
    	while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
    	while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    const int maxn = 50010;
    const int mod = 998244353;
    int a[maxn],b[2][maxn],ans;
    void solve(int l,int r,int d){
    	if(d == 30 || l == r) return;
    	b[0][0] = b[1][0] = 0;
    	for(int i=l;i<=r;++i){
    		if((a[i]>>d)&1) b[1][++b[1][0]] = a[i];
    		else b[0][++b[0][0]] = a[i];
    	}
    	ans += ((1<<d)*(b[1][0]*b[0][0]%mod)) % mod;
    	if(ans >= mod) ans -= mod;
    	for(int i=1;i<=b[1][0];++i) a[l+i-1] = b[1][i];
    	for(int i=1;i<=b[0][0];++i) a[l+b[1][0]-1+i] = b[0][i];
    	int mid = l+b[1][0]-1;
    	if(l <= mid) solve(l,mid,d+1);
    	if(mid+1 <= r) solve(mid+1,r,d+1);
    }
    inline void work(int num){
    	int n;read(n);
    	for(int i=1;i<=n;++i) read(a[i]);
    	ans = 0;solve(1,n,0);
    	printf("Case #%d: %d
    ",num,ans<<1);
    }
    int main(){
    	int T;read(T);
    	for(int i=1;i<=T;++i) work(i);
    	getchar();getchar();
    	return 0;
    }
    
  • 相关阅读:
    jquery load加载页面内ajax返回的div不能响应页面js的问题的解决方案
    JQuery跳出each循环的方法(包含数组遍历)
    fpm 配置详解
    curl模拟Http请求
    git 修改commit信息
    git-ssh 配置和使用
    初始化目录,并且添加到远程仓库
    【PHP代码审计】 那些年我们一起挖掘SQL注入
    【PHP代码审计】 那些年我们一起挖掘SQL注入
    【PHP代码审计】 那些年我们一起挖掘SQL注入
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6481012.html
Copyright © 2020-2023  润新知