题意:给一个数A,有6种操作,+a,-a,+b,-b,+(a+b),-(a+b),每次选择一种,用最少的次数变成B。

思路:由于不同的操作先后顺序对最后的结果没有影响,并且加一个数与减一个相同的数不能同时有,如果有,把它们都去掉结果更优。所以不妨设+a操作进行了x次(x为负表示-a操作进行了|x|次,y同理),+b操作进行了y次,那么问题转化为ax + by = |A-B|的解,使得结果最小,其中如果x,y异号,结果为|x|+|y|,同号则为max(|x|,|y|,因为+a,+b或-a,-b可以合并)。令c=|A-B|,如果c%gcd(a,b)!=0,这个显然是没有解的,直接输出-1。否则令a=a/g,b=b/g,c=c/g,其中gcd(a,b)=1,令ax+by=1的一个解为(x0,y0),则方程的通解可以表示为(x0+kb,y0-ka),下面进行关键的一步:由于ax+bx=c可以转化为c个ax+bx=1相加,所以ax+bx=c的解可以表示为(cx0+Kb,cy0-Ka)(K取任意整数),这里a,b,c,x0,y0都是已知的,K是个变量,K确定后那么答案也就确定了,由于答案是K的单峰函数所以可以三分一下,求得最小答案。由于K的范围不确定,需要用大整数=_=(醉了)!具体看代码。

  1 #pragma comment(linker, "/STACK:10240000,10240000")
  2
  3 #include <iostream>
  4 #include <cstdio>
  5 #include <algorithm>
  6 #include <cstdlib>
  7 #include <cstring>
  8 #include <map>
  9 #include <queue>
 10 #include <deque>
 11 #include <cmath>
 12 #include <vector>
 13 #include <ctime>
 14 #include <cctype>
 15 #include <set>
 16 #include <bitset>
 17 #include <functional>
 18 #include <numeric>
 19 #include <stdexcept>
 20 #include <utility>
 21
 22 using namespace std;
 23
 24 #define mem0(a) memset(a, 0, sizeof(a))
 25 #define mem_1(a) memset(a, -1, sizeof(a))
 26 #define lson l, m, rt << 1
 27 #define rson m + 1, r, rt << 1 | 1
 28 #define define_m int m = (l + r) >> 1
 29 #define rep_up0(a, b) for (int a = 0; a < (b); a++)
 30 #define rep_up1(a, b) for (int a = 1; a <= (b); a++)
 31 #define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
 32 #define rep_down1(a, b) for (int a = b; a > 0; a--)
 33 #define all(a) (a).begin(), (a).end()
 34 #define lowbit(x) ((x) & (-(x)))
 35 #define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
 36 #define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
 37 #define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
 38 #define pchr(a) putchar(a)
 39 #define pstr(a) printf("%s", a)
 40 #define sstr(a) scanf("%s", a)
 41 #define sint(a) scanf("%d", &a)
 42 #define sint2(a, b) scanf("%d%d", &a, &b)
 43 #define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
 44 #define pint(a) printf("%d\n", a)
 45 #define test_print1(a) cout << "var1 = " << a << endl
 46 #define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
 47 #define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
 48
 49 typedef long long LL;
 50 typedef pair<int, int> pii;
 51 typedef vector<int> vi;
 52
 53 const int dx[8] = {0, 0, -1, 1, 1, 1, -1, -1};
 54 const int dy[8] = {-1, 1, 0, 0, 1, -1, 1, -1 };
 55 const int maxn = 102;
 56 const int md = 10007;
 57 const int inf = 1e9 + 7;
 58 const LL inf_L = 1e18 + 7;
 59 const double pi = acos(-1.0);
 60 const double eps = 1e-4;
 61
 62 template<class T>T gcd(T a, T b){return b==0?a:gcd(b,a%b);}
 63 template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
 64 template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
 65 template<class T>T condition(bool f, T a, T b){return f?a:b;}
 66 template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
 67 int make_id(int x, int y, int n) { return x * n + y; }
 68
 69 const int maxI = 1e8;
 70 const int Len = 8;
 71
 72 struct BigInt {
 73     vi num;
 74     bool symbol;
 75     BigInt() { num.clear(); symbol = 0; }
 76     BigInt(int x) { symbol = 0; if (x < 0) { symbol = 1; x = -x; } num.push_back(x % maxI); if (x >= maxI) num.push_back(x / maxI); }
 77     BigInt(bool s, vi x) { symbol = s;  num = x; }
 78     BigInt(char s[]) {
 79         int len = strlen(s), x = 1, sum = 0, p = s[0] == '-';
 80         symbol = p;
 81         for (int i = len - 1; i >= p; i--) {
 82             sum += (s[i] - '0') * x;
 83             x *= 10;
 84             if (x == 1e8 || i == p) {
 85                 num.push_back(sum);
 86                 sum = 0;
 87                 x = 1;
 88             }
 89         }
 90         while (num.back() == 0 && num.size() > 1) num.pop_back();
 91     }
 92
 93     void push(int x) { num.push_back(x); }
 94
 95     BigInt abs() const { return BigInt(false, num); }
 96
 97     bool smaller(const vi &a, const vi &b) const {
 98         if (a.size() != b.size()) return a.size() < b.size();
 99         for (int i = a.size() - 1; i >= 0; i--) {
100             if (a[i] != b[i]) return a[i] < b[i];
101         }
102         return 0;
103     }
104
105     bool operator < (const BigInt &p) const {
106         if (symbol && !p.symbol) return true;
107         if (!symbol && p.symbol) return false;
108         if (symbol && p.symbol) return smaller(p.num, num);
109         return smaller(num, p.num);
110     }
111
112     bool operator > (const BigInt &p) const {
113         return p < *this;
114     }
115
116     bool operator == (const BigInt &p) const {
117         return !(p < *this) && !(*this < p);
118     }
119
120     bool operator >= (const BigInt &p) const {
121         return !(*this < p);
122     }
123
124     bool operator <= (const BigInt &p) const {
125         return !(p < *this);
126     }
127
128     vi add(const vi &a, const vi &b) const {
129         vi c;
130         c.clear();
131         int x = 0;
132         for (int i = 0; i < a.size(); i++) {
133             x += a[i];
134             if (i < b.size()) x += b[i];
135             c.push_back(x % maxI);
136             x /= maxI;
137         }
138         for (int i = a.size(); i < b.size(); i++) {
139             x += b[i];
140             c.push_back(x % maxI);
141             x /= maxI;
142         }
143         if (x) c.push_back(x);
144         while (c.back() == 0 && c.size() > 1) c.pop_back();
145         return c;
146     }
147
148     vi sub(const vi &a, const vi &b) const {
149         vi c;
150         c.clear();
151         int x = 1;
152         for (int i = 0; i < b.size(); i++) {
153             x += maxI + a[i] - b[i] - 1;
154             c.push_back(x % maxI);
155             x /= maxI;
156         }
157         for (int i = b.size(); i < a.size(); i++) {
158             x += maxI + a[i] - 1;
159             c.push_back(x % maxI);
160             x /= maxI;
161         }
162         while (c.back() == 0 && c.size() > 1) c.pop_back();
163         return c;
164     }
165
166     vi mul(const vi &a, const vi &b) const {
167         vi c;
168         c.resize(a.size() + b.size());
169         for (int i = 0; i < a.size(); i++) {
170             for (int j = 0; j < b.size(); j++) {
171                 LL tmp = (LL)a[i] * b[j] + c[i + j];
172                 c[i + j + 1] += tmp / maxI;
173                 c[i + j] = tmp % maxI;
174             }
175         }
176         while (c.back() == 0 && c.size() > 1) c.pop_back();
177         return c;
178     }
179
180     vi div(const vi &a, const vi &b) const {
181         vi c(a.size()), x(1, 0), y(1, 0), z(1, 0), t(1, 0);
182         y.push_back(1);
183         for (int i = a.size() - 1; i >= 0; i--) {
184             z[0] = a[i];
185             x = add(mul(x, y), z);
186             if (smaller(x, b)) continue;
187             int l = 1, r = maxI - 1;
188             while (l < r) {
189                 int m = (l + r + 1) >> 1;
190                 t[0] = m;
191                 if (smaller(x, mul(b, t))) r = m - 1;
192                 else l = m;
193             }
194             c[i] = l;
195             t[0] = l;
196             x = sub(x, mul(b, t));
197         }
198         while (c.back() == 0 && c.size() > 1) c.pop_back();
199         return c;
200     }
201
202     BigInt operator + (const BigInt &p) const{
203         if (!symbol && !p.symbol) return BigInt(false, add(num, p.num));
204         if (!symbol && p.symbol) return *this >= p.abs()? BigInt(false, sub(num, p.num)) : BigInt(true, sub(p.num, num));
205         if (symbol && !p.symbol) return (*this).abs() > p? BigInt(true, sub(num, p.num)) : BigInt(false, sub(p.num, num));
206         return BigInt(true, add(num, p.num));
207     }
208
209     BigInt operator - (const BigInt &p) const {
210         return *this + BigInt(!p.symbol, p.num);
211     }
212
213     BigInt operator * (const BigInt &p) const {
214         BigInt res(symbol ^ p.symbol, mul(num, p.num));
215         if (res.symbol && res.num.size() == 1 && res.num[0] == 0) res.symbol = false;
216         return res;
217     }
218
219     BigInt operator / (const BigInt &p) const {
220         if (p == BigInt(0)) return p;
221         BigInt res(symbol ^ p.symbol, div(num, p.num));
222         if (res.symbol && res.num.size() == 1 && res.num[0] == 0) res.symbol = false;
223         return res;
224     }
225
226     BigInt operator % (const BigInt &p) const {
227         return *this - *this / p * p;
228     }
229
230     void show() const {
231         if (symbol) putchar('-');
232         printf("%d", num[num.size() - 1]);
233         for (int i = num.size() - 2; i >= 0; i--) {
234             printf("%08d", num[i]);
235         }
236         putchar('\n');
237     }
238
239     int TotalDigit() const {
240         int x = num[num.size() - 1] / 10, t = 1;
241         while (x) {
242             x /= 10;
243             t++;
244         }
245         return t + (num.size() - 1) * Len;
246     }
247
248 };
249 typedef BigInt bi;
250 bi A, B, a, b;
251 bi x, y, d, t;
252 char s[100];
253 void gcd(bi a, bi b, bi &d, bi &x, bi &y) {
254     if (b == 0) {
255         d = a;
256         x = 1;
257         y = 0;
258     }
259     else {
260         gcd(b, a % b, d, y, x);
261         y = y - x * (a / b);
262     }
263 }
264
265 bi f(bi k) {
266     bi p = t * x + k * b;
267     bi q = t * y - k * a;
268     if (p > 0 && q > 0 || p < 0 && q < 0) return max(p.abs(), q.abs());
269     return p.abs() + q.abs();
270 }
271
272 int main() {
273     //freopen("in.txt", "r", stdin);
274     int T;
275     cin >> T;
276     while (T --) {
277         cin >> s;
278         A = bi(s);
279         cin >> s;
280         B = bi(s);
281         cin >> s;
282         a = bi(s);
283         cin >> s;
284         b = bi(s);
285         t = (A - B).abs();
286         bi g = gcd(a, b);
287         if (!(t % g == 0)) {
288             puts("-1");
289             continue;
290         }
291         a = a / g;
292         b = b / g;
293         t = t / g;
294
295         gcd(a, b, d, x, y);
296
297         bi l = "-100000000000000000", r = "100000000000000000";
298         while (r - l > 2) {
299             bi m1 = l + (r - l) / 3, m2 = r - (r - l) / 3;
300             if (f(m1) > f(m2)) l = m1 + 1;
301             else r = m2;
302         }
303         bi ans = f(l);
304         min_update(ans, f(l + 1));
305         min_update(ans, f(l + 2));
306         ans.show();
307     }
308 }

View Code

转载于:https://www.cnblogs.com/jklongint/p/4480791.html

[zoj3593]扩展欧几里得+三分相关推荐

  1. 扩展欧几里得 POJ 1061

    感觉这道题目的数据好水啊...我的代码我都觉得姿势特别奇怪...竟然还过了... 好吧,原来不是姿势奇怪,而是逆元需要用的时候是余数也需要的时候,这里的余数是不需要的,所以就AC了 就说一下碰到的问题 ...

  2. 求逆元(线性求逆元)及其扩展欧几里得

    线性求逆元模板: int inv[maxn]; void initInverse(){inv[1] = 1;for(int i = 2; i <= maxn; i++)inv[i] = (p - ...

  3. poj-青蛙的约会(扩展欧几里得)nyoj-小柯的约会

    由题意可列出方程 x + m * s - (y + n * s) = k * l; 化简得   (n-m)*s + k*l = x - y 化简得   (n-m)*s = x - y (mod l); ...

  4. [模板]欧几里得算法/扩展欧几里得

    最大公因数(欧几里得算法) $gcd(a,b)=gcd(b\%a,a)$(不一定需要a<b) $gcd(0,b)=b$ 1 inline int gcd(int a,int b){ 2 retu ...

  5. “景驰科技杯”2018年华南理工大学程序设计竞赛 H-对称与反对称(扩展欧几里得求逆元)

    题目链接 题目描述: 给出一个N*N的方阵A.构造方阵B,C: 使得A = B + C.其中 B为对称矩阵,C为反对称矩阵. 对于方阵S中的任意元素,若(S)ij = (S)ji,则称S为对称矩阵 对 ...

  6. Strange Optimization(扩展欧几里得)

    Strange Optimization Accepted : 67   Submit : 289 Time Limit : 1000 MS   Memory Limit : 65536 KB Str ...

  7. CodeForces - 724C Ray Tracing(扩展欧几里得解方程)

    题目链接:点击查看 题目大意:在 n∗mn*mn∗m 的矩阵中,从点 (0,0)(0,0)(0,0) 发射一个小球,以四十五度的方向出发,速度是 2\sqrt{2}2​,当碰到壁时,会进行反射:当碰到 ...

  8. 牛客多校3 - Fraction Construction Problem(扩展欧几里得)

    题目链接:点击查看 题目大意:给出 a 和 b ,求解满足条件的 c,d,e,f ,使得: d < b f < b c,e 均为小于等于 4e12 的正整数 题目分析:分情况讨论一下,首先 ...

  9. POJ - 1061 青蛙的约会(扩展欧几里得)

    题目链接:点击查看 题目大意:两只青蛙在一个单向循环数轴上跳动,给出初始位置和每秒跳动的距离以及数轴长度,问是否可以相遇,若能相遇求出最小时间 题目分析:自从第一次接触扩展欧几里得以来已经有半年时间了 ...

最新文章

  1. 对比es1.x和es2.0纹理加载方法
  2. python开发是做什么的-python开发工程师是做什么的
  3. ibatis轻松入门
  4. 【BZOJ1934】善意的投票(网络流)
  5. python 多版本管理
  6. 二分法(递归非递归)
  7. Ajax和JSON-学习笔记04【JSON_解析器】
  8. 流水线、超流水线、超标量技术对比
  9. Java的数据库编程之背景概述
  10. dubbo调用超时回滚_如何处理Dubbo调用超时?
  11. Power BI Desktop报告中的Web URL配置
  12. P1551 亲戚题解
  13. 求最长XX序列的两种方法
  14. video上传架构设计与实现
  15. 基于pywifi库的暴力破解wifi方法
  16. PLC有几种编程语言以及它们的特点是什么
  17. 如何在购买笔记本电脑的时候选择配置?这篇笔记本电脑的配置参数解析你值得拥有。
  18. windows linux 共存,Windows与Linux共存
  19. flash AS3常用公式
  20. Lab3 Attack Lab

热门文章

  1. C3P0连接池配置方式
  2. target-action设计模式--主要为Button的方法重写
  3. 开启服务器,自动加载类是否需要开辟新的线程研究
  4. Ubuntu enca命令可以用来查看文件的编码格式
  5. Perl Redis 连接测试脚本,获取list长度
  6. Centos7安装dig命令
  7. css3-13 css3的3D动画如何实现
  8. 《OpenACC并行程序设计:性能优化实践指南》一 第2章 性能导向开发
  9. 单元测试的四大具体效益
  10. Linux命令之cut详解