AT_abc347_d 题解

纯脑掺题目。

最开始的思路很飞舞我就不写了。

首先先是 -1 的情况(\(c\)\(C\)\(popcount\)):

  • \(a+b+c\equiv 1\pmod 2\)
  • \(a+b+c\gt 120\)
  • \(a\gt b+c,b\gt c+a,c\gt a+b\).

第一个很容易想到。

第二个是因为题中 \(X,Y\) 的上限限制。

第三个是因为很明显搞不了。

后面的构造:

为方便,让 \(n_{i,j}\) 代表满足 \(X\)\(Y\) 的二进制表示的第 \(k\) 位分别是 \(i\)\(j\)\(k\) 的个数。

\(S_0\) 是由 \(n_{0,0}\)\((0,0)\)\(n_{1,1}\)\((1,1)\) 组成的序列,\(S_1\) 是由 \(n_{0,1}\)\((0,1)\)\(n_{1,0}\)\((1,0)\) 组成的序列。(\((i,j)\) 表示 \(X\) 这位选 \(i\)\(Y\) 这位选 \(j\)

对于二进制下 \(C\) 的每一位,设 \(p\) 为这位的数字。(位从后向前进行递减)

首先,删掉 \(S_p\) 的最后一个二元组,代表它被使用过了。

\((x,y)\) 为刚刚删掉的元素,并将 \(X\)\(Y\) 的这位分别设为 \(x\)\(y\)

然后,我们根据以上定义以及题目,发现:

  • \(popcount(X)=a\iff n_{1,0}+n_{1,1}=a\)
  • \(popcount(Y)=b\iff n_{0,1}+n_{1,1}=b\)
  • \(X\oplus Y=C\implies n_{1,0}+n_{0,1}=popcount(C)\)

又因为 \(\sum n_{i,j}=60\)(总方案数就是整体),于是我们可以推出:

\[n_{0,0}=60-\frac{a+b+c}{2} \]

\[n_{0,1}=\frac{-a+b+c}{2} \]

\[n_{1,0}=\frac{a-b+c}{2} \]

\[n_{1,1}=\frac{a+b-c}{2} \]

没了。

#include<stdio.h>
#include<bits/stdc++.h>
#define N 1000010
#define MOD 998244353
#define esp 1e-8
#define INF 999999999999999999
#define LL long long
#define rep(i,a,b,g) for(LL i=a;i<=b;i+=g)
#define rem(i,a,b,g) for(LL i=a;i>=b;i-=g)
#define repn(i,a,b,g) for(LL i=a;i<b;i+=g)
#define remn(i,a,b,g) for(LL i=a;i>b;i-=g)
#define pll pair<LL,LL>
#define mkp(x,y) make_pair(x,y)
#define i128 __int128
#define lowbit(x) ((x)&(-(x)))
#define lc (u<<1)
#define rc (u<<1|1)
using namespace std;
void read(i128 &x)
{
	i128 f=1;
	x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=x*10+ch-'0';
		ch=getchar();
	}
	x*=f;
}
void writing(i128 x)
{
	if(x>=10)writing(x/10);
	putchar(x%10+'0');
}
void write(i128 x)
{
	if(x<0)
	{
		cout<<'-';
		x=-x;
	}
	writing(x);
}
LL a,b,C,c;
LL popcount(LL x)
{
	LL sum=0;
	while(x)
	{
		if(x&1)sum++;
		x/=2;
	}
	return sum;
}
int main()
{
	cin>>a>>b>>C;
	c=popcount(C);
	if((a+b+c)%2!=0||a+b+c>120||a>b+c||b>c+a||c>a+b)
	{
		cout<<-1<<endl;
		return 0;
	}
	LL n00=60-(a+b+c)/2;
	LL n01=(-a+b+c)/2;
	LL n10=(a-b+c)/2;
	LL n11=(a+b-c)/2;
	LL bx,by,nb;
	bx=by=0;
	nb=60;
	while(nb--)
	{
		bx*=2;
		by*=2;
		if(1&(C>>nb))
		{
			if(n10)
			{
				bx++;
				n10--;
			}
			else
			{
				by++;
				n01--;
			}
		}
		else
		{
			if(n00)
			{
				n00--;
			}
			else
			{
				bx++;
				by++;
				n11--;
			}
		}
	}
	cout<<bx<<' '<<by<<endl;
	return 0;
}
posted @   cppom  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
  1. 1 世末歌者 乐正绫
世末歌者 - 乐正绫
00:00 / 00:00
An audio error has occurred.

蝉时雨 化成淡墨渲染暮色

渗透着 勾勒出足迹与车辙

欢笑声 与漂浮的水汽饱和

隔着窗 同城市一并模糊了

拨弄着 旧吉他 哼着四拍子的歌

拨弄着 旧吉他 哼着四拍子的歌

回音中 一个人 仿佛颇悠然自得

等凉雨 的温度 将不安燥热中和

寻觅着 风的波折

我仍然在无人问津的阴雨霉湿之地

我仍然在无人问津的阴雨霉湿之地

和着雨音 唱着没有听众的歌曲

人潮仍是漫无目的地向目的地散去

忙碌着 无为着 继续

等待着谁能够将我的心房轻轻叩击

等待着谁能够将我的心房轻轻叩击

即使是你 也仅仅驻足了片刻便离去

想着或许 下个路口会有谁与我相遇

哪怕只 一瞬的 奇迹

夏夜空 出现在遥远的记忆

夏夜空 出现在遥远的记忆

绽放的 璀璨花火拥着繁星

消失前 做出最温柔的给予

一如那些模糊身影的别离

困惑着 拘束着 如城市池中之鱼

困惑着 拘束着 如城市池中之鱼

或哽咽 或低泣 都融进了泡沫里

拖曳疲惫身躯 沉入冰冷的池底

注视着 色彩褪去

我仍然在无人问津的阴雨霉湿之地

我仍然在无人问津的阴雨霉湿之地

和着雨音 唱着没有听众的歌曲

人潮仍是漫无目的地向目的地散去

忙碌着 无为着 继续

祈求着谁能够将我的心房轻轻叩击

祈求着谁能够将我的心房轻轻叩击

今天的你 是否会留意并尝试去靠近

因为或许 下个路口仍是同样的结局

不存在 刹那的 奇迹

极夜与永昼

极夜与永昼

别离与欢聚

脉搏与呼吸

找寻着意义

我仍然在无人问津的阴雨霉湿之地

我仍然在无人问津的阴雨霉湿之地

和着雨音 唱着卖不出去的歌曲

浮游之人也挣扎不已执着存在下去

追逐着 梦想着 继续

请别让我独自匍匐于滂沱世末之雨

请别让我独自匍匐于滂沱世末之雨

和着雨音 唱着见证终结的歌曲

人们终于 结束了寻觅呆滞伫立原地

哭泣着 乞求着 奇迹

用这双手 拨出残缺染了锈迹的弦音

用这双手 拨出残缺染了锈迹的弦音

都隐没于淋漓的雨幕无声无息

曲终之时 你是否便会回应我的心音

将颤抖的双手牵起

迎来每个人的结局

点击右上角即可分享
微信分享提示