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\)(总方案数就是整体),于是我们可以推出:
没了。
#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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现