当前位置: 首页 > news >正文

洛谷P13030 [GCJ 2021 #1B] Subtransmutation

0x1f 关于猜想

看完题目后,注意力好的同学可能会发现:有解的充要条件是所有所需的金属编号模 \(\gcd(A,B)\) 同余。

0x2f 关于证明:

根据题意,我们可以将 \(i\) 分解成 \(j\) 这个操作,看作是 \(i\) 经过若干次减 \(A\) 和若干次减 \(B\) 得到了 \(j\),即 \(i-Ax-By=j\)

\(d=\gcd(A,B)\)

必要性

我们知道,最终的答案 \(S\) 经过分解后能够得到所有我们所需要的金属。对于每一块所需的金属编号 \(M_i\),都存在自然数 \(x_i\)\(y_i\) 使得 \(S-Ax_i-By_i=M_i\),变形可得 \(S-M_i=Ax_i+By_i\)

由于 \(d\mid (Ax_i+By_i)\),所以 \(d\mid (S-M_i)\),即 \(S \equiv M_i (\bmod d)\)

不难得出,所有的所需编号都模 \(d\) 同余,该命题得证。

充分性

先考虑只有两块金属 \(M_1\)\(M_2\) 的情况:

我们知道若有解,就一定存在一块金属 \(S'\) 使得它能够分解成 \(M_1\)\(M_2\),即 \(S'-Ax_1-By_1=M_1\)\(S'-Ax_2-By_2=M_2\),为满足题目条件,我们就令 \(x_1,x_2,y_1,y_2 \in N_+\)。问题就是是否存在这样的 \(x_1,x_2,y_1,y_2\)

我们将上面的两个公式稍加变形:

将两式合并。

\[\begin{cases} S'-Ax_1-By_1=M_1\\ S'-Ax_2-By_2=M_2 \end{cases} \]

因为 \(M_2 \equiv M_1 \mod d\)。所以 \(d\mid M_2-M_1\)

我们令 \(M_2-M_1=kd\)。最终,公式就变成了 \(A(x_1-x_2)+B(y_1-y_2)=kd\)

有了上面的推论,无解情况就很好判断了。那么其他的就是有解情况了。

我们可以保证其他情况都有解,且这个解与前面的所有所需编号模 \(\gcd(A,B)\) (即上文中的 \(d\))同余。因此,我们只要从 \(n\) 出发,枚举所有可能的 \(S\) 即可。

我们用 \(mp\) 来记录编号与现有的数量,由于分解得到的编号一定是从大到小的,所以我们将 \(mp\) 按键升序排列。从 \(S\) 出发,一直分解,当遍历到 \(j\) 时,它的数量已经是固定的,若 \(j\) 是我们最终需要的金属,先判断够不够,不够直接退出循环,够了则减去所需量,再进行分解。知道最后全部分解完后,\(mp\) 为空,结束遍历。

最后,我们遍历数组 \(now\),若全部金属都已足够,就可以输出答案结束循环了。

0x3f 关于代码

\(\huge \mathscr{Code}\)

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+100;
int T,n,m,A,B,z,U[N],now[N];
int main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>T;for(int _=1;_<=T;_++){cin>>n>>A>>B;int g = __gcd(A,B),flag = 1;m = -1;for(int i=1;i<=n;i++){cin>>U[i];if(U[i]){if(m==-1) m = i%g;else flag &= (i%g==m);}}if(!flag){cout<<"Case #"<<_<<": "<<"IMPOSSIBLE\n";continue;}int pos = n;while(true){for(int j=1;j<=n;j++) now[j] = U[j];map<int,int,greater<int>> mp;mp[pos] = 1;for(auto e:mp){int key = e.first,val = e.second;if(key<=n && now[key]){if(now[key]>val) break;else{val -= now[key];now[key] = 0;}}if(key>A) mp[key-A] += val;if(key>B) mp[key-B] += val;}bool flagg = 1;for(int j=1;j<=n;j++) flagg &= (now[j]==0);if(flagg){cout<<"Case #"<<_<<": "<<pos<<'\n';break;}pos += g;}}return 0;
}
http://www.aitangshan.cn/news/65.html

相关文章:

  • idempiere安装
  • 如何安装 Git (windows/mac/linux)
  • 拆解Agent如何实现“听懂→规划→搞定”全流程
  • ActiveMQ 设置用户名密码
  • MySQL 8.0.42 手动部署全过程(CentOS 7 虚拟机 Linux)
  • PDF处理控件Aspose.PDF教程:在C#、Java、Python中快速缩小PDF
  • 自动化测试框架选型指南:5大主流工具实战对比
  • Re:从零开始的动态凸壳
  • 资产管理系统 - microsoft
  • G1 垃圾回收器调优
  • 面相对象编程:类和对象
  • 学习笔记:Query Transformation- Distinct Aggregate Transformation
  • 安卓
  • 妈妈再也不用担心我画图太丑了,画图神器:plantUML
  • 测试用例精简技术全解析:从原理到实践
  • 优化DeepSpeed ZeRO在低成本硬件上的运行效率
  • 读书笔记:数据库事务处理的那些坑与妙招
  • arduino 工具栏消失
  • # 常见算法板子(一)
  • 【算法分享】字典树 — 插入、查询与状态标记详解
  • 8.10
  • Windows 2003 系统如何修改网卡DNS?
  • Python 内置模块 base64:编码与解码的艺术
  • Webstorm运行显示404 not found的问题解决方案。
  • 一文带你彻底学会 Git 代码管理
  • arcgispro的软件说明文档和使用技巧
  • InnoDB为什么不用跳表,Redis为什么不用B+树?
  • c++算法竞赛输入输出优化
  • JS中对输入的金额进行大写转换(支持两位小数)
  • 集训内容总结 day13:模拟赛 Round6