ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[CodeChef(July)221 Div.4 G]Find A, B, C

2022-07-11 21:05:29  阅读:144  来源: 互联网

标签:int tt 整数 Find leq oplus include July Div.4


做题时间:2022.7.11

\(【题目描述】\)

有三个非负整数 \(A,B,C\) 与一个正整数 \(N(N\leq 2\times 10^5)\) 满足 \(A,B,C\leq N\) ,给定 \(N+1\) 个函数 \(f(0),f(1),...,f(N)\) ,对于 \(\forall i,0\leq i\leq N\) 满足 \(f(i)=(A \oplus i )+(B\oplus i)+(C\oplus i)\) ,求出任意一组满足条件的 \(A,B,C\) (题目保证有解)

\(【输入格式】\)

第一行一个整数 \(T\) 表示数据组数
每组数据第一行一个整数 \(N\)
第二行 \(N+1\) 个整数表示 \(f\)

\(【输出格式】\)

共 \(T\) 行,每行三个整数表示 \(A,B,C\)

\(【考点】\)

位运算

\(【做法】\)

对于两个不同的 \(f(i)\) 和 \(f(j)\) 来说如果 \(i\) 与 \(j\) 在二进制表示下仅有一位相同,那么就可以推出那一位上 \(A,B,C\) 的情况

具体而言,若 \(i\) 与 \(j\) 的第 \(k\) 位不相同(假设 \(i_k=1,j_k=0\) ),那么 \(f(j)-f(i)=(A\oplus i)-(A\oplus j)+(B\oplus i)-(B\oplus j)+(C\oplus i)-(C\oplus j)=2^k\times (A_k+B_k+C_k)\)

即:

\[A_k+B_k+C_k=\frac{f(j)-f(i)}{2^k} \]

也就是说我们能够知道三个数的第 \(k\) 位的和。 注意:在确定了三者的和后, \(A_k\) , \(B_k\) 与 \(C_k\) 是无所谓谁是1谁是0的 ,因为在运算过程中 \(A,B,C\) 总是一起参与,且位运算不影响进位。

对于 \(A_k,B_k,C_k\) 的第 \(k\) 位而言,如果其中一个是1,那么异或后对 \(A_k+B_k+C_k\) 的贡献为 \(-1\) ,若它是 \(0\) ,那么异或后对 \(A_k+B_k+C_k\) 的贡献为 \(1\) ,所以最后 \(A_k+B_k+C_k\) 的值为 \([-3,-1,1,3]\) ,对应1的个数为 \([3,2,1,0]\)

只要知道所有的 \(0\leq 2^k\leq N\) 的 \(k\) 即可,可以通过 \(f(2^k)\) 与 \(f(0)\) 进行上述计算,得出第 \(k\) 位的结果。

需要注意的是,给 \(A_k,B_k,C_k\) 赋值的时候其中一个可能超过 \(N\) ,因此可以考虑倒序处理,并且每次率先给最小的赋值。

\(【代码】\)

#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;
const int N=1e5+50;
int f[N],n,T;
int main()
{
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		int a[3]={0,0,0};
		for(int i=0;i<=n;i++) scanf("%d",&f[i]);
		
		
		for(int k=18;k>=0;k--){//倒序处理 
			int i=(1<<k);
			if(i>n) continue;
			int tt;
			sort(a,a+3);//将a,b,c中最小的率先赋值,平均三者大小 
			
			//计算(f(i)-f(0))/2^k的值 
			if(f[i]>f[0]){//大于0 
				tt=(f[i]-f[0])/i;
				if(tt==1) a[0]^=i;
			}
			else{//小于0 
				tt=(f[0]-f[i])/i;
				if(tt==3) a[0]^=i,a[1]^=i,a[2]^=i;
				if(tt==1) a[0]^=i,a[1]^=i;
			}
		}
		printf("%d %d %d\n",a[0],a[1],a[2]);
	}
	return 0;
}

标签:int,tt,整数,Find,leq,oplus,include,July,Div.4
来源: https://www.cnblogs.com/Unlimited-Chan/p/16467851.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有