题解 CF1365G 【Secure Password】

这是一篇关于CF1365G问题的题解,讨论了一道需要巧妙思维的题目。文章介绍了如何在交互次数有限的情况下,利用二进制位表示法优化解决方案。通过设立状态fi,j来表示ak的或和,然后计算Px值,其中i是x二进制位为1的位置。" 126817998,15389502,Vue2 & Vue3:使用class风格的composition API,"['Vue.js', 'JavaScript', '前端开发']

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

题解 - C F 1365 G \mathrm{CF1365G} CF1365G

题目意思

S o l \mathrm{Sol} Sol

  • 很巧妙的一道思维题

我们首先考虑如果可以交互的次数较多怎么做?

我们可以设 f i , j f_{i,j} fi,j 表示对于 a k a_{k} ak 的或和,其中 k k k 的第 i i i 位为 j j j。那么统计答案时候比如 P 6 = f 3 , 0 ∣ f 2 , 0 ∣ f 1 , 1 P_6=f_{3,0}|f_{2,0}|f_{1,1} P6=f3,0f2,0f1,1,因为 ( 6 ) 2 = [ 1 , 1 , 0 ] (6)_{2}=[1,1,0] (6)2=[1,1,0]

这样的做法交互次数肯定大于 13 13 13 次,我们考虑如何优化。一个方法就是把每个数的下标用二进制位表示,因为 n ≤ 1 0 3 n\leq 10^3 n103,并且 C 13 6 > 1 0 3 C_{13}^{6}>10^3 C136>103 所以我们对于 13 13 13 个二进制位以及 6 6 6 1 1 1 就足够表示所有下标了。

我们这次不再对下标进行dp,而是对其二进制编号我们用 v i v_i vi 记录,其实 v i = f i , 0 v_i=f_{i,0} vi=fi,0。那么此时我们计算 P x = ∑ v i P_x=\sum v_i Px=vi 其中 i i i x x x 的二进制为 1 1 1 的位置。

C o d e \mathrm{Code} Code


int n,m,A[2005],t[15];
vector<int> vec[15];

inline int query(int x)
{
	if(!vec[x].size()) return 0;
	cout<<"?"<<" "<<(int)vec[x].size()<<" ";
	For(i,0,(int)vec[x].size()-1) cout<<vec[x][i]<<" ";
	cout<<endl;
	cin>>m;
	return m;
}

signed main()
{
	io.read(n);
	int S=(1ll<<13)-1;
	For(i,0,S) if(__builtin_popcount(i)==6) 
	{
		A[++*A]=i;
		For(j,0,12) if(!(i&(1ll<<j))) vec[j].pb(*A);
		if((*A)==n) break;
	}
	For(i,0,12) t[i]=query(i);
	cout<<"!"<<" ";
	For(i,1,n) 
	{
		int sum=0,x=A[i];
		For(j,0,12) if((x>>j)&1ll) sum|=t[j];
		io.write(sum),putchar(' ');
	}
	return 0;
}
		

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值