P2520 [HAOI2011]向量 题解
转换题意
为了表述方便,我们设目标向量为 \((s_1,s_2)\),和题目描述稍有差别。
我们首先只考虑目标向量的横坐标。由于横坐标为 \(a\),\(-a\),\(b\),\(-b\) 的向量均可任意使用,我们可以得到一个不定方程 \(xa+yb=s_1\)。
之后,我们再考虑目标向量的纵坐标,由于 \(x+k-k=x\),我们可以得到第二个不定方程 \((x+2k_1)b+(y+2k_2)a=s_2\) 。
联立上述两个不定方程,题意便转化为了这两个不定方程是否有解。
数学推理
单独考虑第一个不定方程,根据扩欧相关知识,我们可以知道该不定方程有解当且仅当 \(\gcd(a,b)\ |\ s_1\),直接判断即可。
然后,我们设第一个不定方程的特解为 \(x_0\),\(y_0\),那么其通解为 \(x_0+k \frac{b}{\gcd(a,b)}\),\(y_0-k\frac{a}{\gcd(a,b)}\)。
把通解带入第二个不定方程,得 \((x_0+k \frac{b}{\gcd(a,b)}+2k_1)b+(y_0-k\frac{a}{\gcd(a,b)}+2k_2)a=s_2\)
移项和整理,得 \(2k_1b+2k_2a=s_2-x_0b-y_0a+k(\frac{a^2-b^2}{\gcd(a,b)})\)
把\(k\)视作已知,故原不定方程有解当且仅当 \(\gcd(2a,2b)\ |\ [s_2-x_0b-y_0a+k(\frac{a^2-b^2}{\gcd(a,b)})]\)
即 \(s_2-x_0b-y_0a+k(\frac{a^2-b^2}{\gcd(a,b)})=-t\gcd(2a,2b)\)
再移项,得 \(t\gcd(2a,2b)+k(\frac{a^2-b^2}{\gcd(a,b)})=s_2-x_0b-y_0a\)
这又是一个不定方程,其有解当且仅当\(\gcd(\gcd(2a,2b),k(\frac{a^2-b^2}{\gcd(a,b)}))\ |\ s_2-x_0b-y_0a\)
该不定方程有解时,原不定方程也一定有解。
结论
当且仅当 \(\gcd(a,b)\ |\ s_1\) 且 \(\gcd(\gcd(2a,2b),k(\frac{a^2-b^2}{\gcd(a,b)}))\ |\ s_2-x_0b-y_0a\) 时,目标向量可以被表示。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
inline int r()
{
int s=0,k=1;char c=getchar();
while(!isdigit(c))
{
if(c=='-')k=-1;
c=getchar();
}
while(isdigit(c))
{
s=s*10+c-'0';
c=getchar();
}
return s*k;
}
int q,x,y,s1,s2;
int exgcd(int a,int b)
{
if(!b)
{
x=1;y=0;
return a;
}
int g=exgcd(b,a%b);
int tmp=x;
x=y;
y=tmp-y*(a/b);
return g;
}
signed main()
{
int a,b;
q=r();
for(int i=1;i<=q;i++)
{
a=r();b=r();s1=r();s2=r();
int g=exgcd(a,b);
if(s1%g)
{
cout<<"N"<<endl;
continue;
}
s1/=g;
int x0=x*s1,y0=y*s1;
int g1=exgcd(2*a,2*b);
x0=(x0%g1+g1)%g1;
y0=(y0%g1+g1)%g1;
int c=s2-x0*b-y0*a;
c=(c%g1+g1)%g1;
int gg=exgcd((a*a-b*b)/g,g1);
if(c%gg)
{
cout<<"N"<<endl;
continue;
}
cout<<"Y"<<endl;
}
}
原文地址:https://www.cnblogs.com/lytql/p/15026839.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- LeetCode 242. 有效的字母异位词
- 再见Excel!最强国产开源在线表格Luckysheet走红GitHub
- 快速学习Python之迭代器和生成器
- js事件冒泡
- Deepin创建应用快捷方式
- SecureCRT下Python脚本编写
- 一篇文章上手Vue3中新增的API
- 先电OpenStack卸载脚本
- 先电OpenStack之neutron-vlan脚本
- 【7】进大厂必须掌握的面试题-Java面试-Jsp
- HTML5+JS 可交互360°&柱状全景图浏览
- Spring编译源代码解决spring-core缺少cglib和objenesis的jar包的办法
- 尤大 3 天前发在 GitHub 上的 vue-lit 是啥?
- CSS3旋转实例学习(附3D旋转实例)
- 学会23个linux常用命令,不做前端切图仔~