首页 > 其他分享 >Magic题解

Magic题解

时间:2023-01-11 08:23:07浏览次数:38  
标签:10 Magic int 题解 sum ans oplus 我们

Magic题解

题意简述:

给定\(n\)个数\(a_1,a_2,…,a_n\),设对于数\(x\),\(|x|\)表示其在十进制下的位数,也即\(10^{|x|}\le x<10^{|x|+1}\)

需要计算:

\[\sum_{i=1}^n\sum_{j=i+1}^na_i\oplus a_j \]

数据范围:

\(n\le 5\times 10^4,a_i\le 10^{18}\)

分析

这个数据范围启发我们设计一个带\(\log\)的算法

如果我们设

\(S_k=\)\(\sum_{i=1}^n\sum_{j=i+1}^n[a_i\oplus a_j\ge k]\)

则我们要求解的答案是:

\[\sum_{k=1}^{18}k(S_{10^k}-S_{10^{k+1}})+\frac{n(n-1)}{2}=S_0+S_{10}+…+S_{10^{18}} \]

所以问题转化为求解\(S\)

关于异或的问题,不难想到使用字典树进行求解,设我们已经将所有的\(a\)插入到字典树中。

数据范围是允许我们将求解每一个\(S\)的复杂度为\(O(n\log n)\).这正好就是在字典树中遍历\(n\)个数的复杂度。

这启发我们设计函数solve(s,t)表示对于\(s\)计算其对\(S_t\)的贡献。

设\(s,t\)的二进制表示分别为\((b_k,b_{k-1}…b_1),(c_k,c_{k-1}…c_1)\)

对于答案的计算,可以将其分为两部分:可以在当前位解决的和留在后续解决的。

则我们设指针\(p\)从\(k\)遍历到\(1\),按位统计贡献,将这个过程看作我们不断填数的过程,设所填数为\(x\),其二进制表示为\((d_k,d_{k-1}…d_1)\)

分类讨论:

  1. \(b_p=1,c_p=1\)。此时,我们若想要保持\(x\oplus s>t\)的可能,就需要让\(x\oplus s\)的第\(p\)位为1,也即我们填上\(d_p=0\),此时我们无法计算出答案
  2. \(b_p=0,c_p=1\),类比情况一,填上\(d_p=1\)
  3. \(b_p=1,c_p=0\),此时我们将\(d_p\)填为\(1/0\),当填为\(0\)时,第\(p-1\sim 1\)位无论填什么都可以对答案产生贡献,所以直接累加上\(siz[t[p][0]]\)的贡献并将\(d_p\)填为\(1\)即可。
  4. \(b_p=0,c_p=0\),类比情况三,可以得到算上\(siz[t[p][1]]\)的贡献然后将\(d_p\)填为0即可。

核心代码:

int solve(int s,int tt){//在trie中查找与s异或比t大的数的数量 
	int p=1,ans=0;
	for(int i=60;i>=0;i--){
		if(!p)return ans;
		int x=(s>>i)&1;
		if((tt>>i)&1){
			p=t[p][x^1];
		}
		else{
			ans+=siz[t[p][x^1]];
			p=t[p][x];
		}
	}
	return ans;
}

标签:10,Magic,int,题解,sum,ans,oplus,我们
From: https://www.cnblogs.com/oierpyt/p/17042741.html

相关文章

  • 选数 题解
    选数题解首先,设最初取值为\(x\),按照套路,我们设异或前缀和:\(pre_i=a_1\oplusa_2…\oplusa_i\),设\(f(x)=\left(\left\lfloor\frac{2x}{2^n}\right\rfloor+2x\right)\bmod......
  • Codeforces Round #843 (Div. 2) 题解
    A题目大意给你一个只含字母a,b字符串,要把它拆分成三段,使得其中间那段要么同时小于等于两边要么同时大于等于两边。题解由于只有a,b我们可以分讨解决如果\([2,......
  • CF1783 A-F 题解
    比赛链接:https://codeforces.com/contest/1783连续三场出4题,还行(其实感觉有两场的E都是会做的)A水题//bySkyRainWind#include<bits/stdc++.h>#definemprmake_pai......
  • 「JOI Open 2022」Giraffes 题解
    设我们将要给出的观感好的排列为\(q\),我们希望求出\(\sum[p_i=q_i]\)的最大值(这里指不移动的长颈鹿个数)。结论一:当且仅当左右端点有当前区间最大值或者最小值时条件才......
  • 题解1
    离散化1.为什么要离散化当数据很大的时候,以至于我们不能直接使用它的时候,就要考虑将其用另外一种形式表达,通常是将其映射为数组下标。2.离散化本质本质:映射3.离......
  • charls抓包的乱码问题解决
    1.在charls的安装目录下,去修改配置文件的值----Charles.ini,内容如下   2.SSLproxysetting设置如下图  3.顺便说一下,charls抓取https的包,一定要先安......
  • docker中crontab无法执行导入计划任务问题解决
    问题描述:crontab无法执行导入计划任务解决: ⊙查看文件16进制 hexdump-c./crontab/defalut   发现有\r;crontab中只能直接\n⊙vim文件修改编码   setfile......
  • P3521 题解
    非线段树合并做法。复杂度多一只log,但是好写。跳过不重要的部分,直达核心——如何在递归时计算两棵子树互相的贡献?题解区清一色线段树合并从值域角度考虑。但是显然倍......
  • [IOI2000]邮局 题解
    简要题意线段上有\(V\)个村庄,现在要建\(P\)个邮局,使每个村庄到最近的邮局的距离之和最小。50分做法设\(dp[i][j]\)表示第一个村庄到第\(i\)个村庄,建了\(j\)个......
  • mysql delete大量数据表锁死,kill的线程后线程处于killed状态问题解决
    一、事件起因删除一张500G的表,没有添加任何约束条件,结果好久都没反应,查询锁之后,使用kill杀掉了进程,再次查询的时候,锁还在,trx_state的状态是ROLLINGBACK,使用showprocessl......