首页 > 其他分享 >AtCoder Regular Contest 127 F ±AB

AtCoder Regular Contest 127 F ±AB

时间:2023-09-27 21:15:00浏览次数:49  
标签:AtCoder qB right frac ll mid Regular 127 left

洛谷传送门

AtCoder 传送门

非常妙的题。

先直观感受一下,显然当 \(M\) 大到一定程度后,\([0, M]\) 的所有数都能被取到。考虑 \(V \gets V + Ax + By\),其中 \(V + Ax + By \in [0, M]\)。如果 \(x, y\) 都是正数显然可以取到。如果一正一负,比如 \(x > 0, y \le 0\),那可以先把 \(V\) 一直减 \(B\) 直到减够 \(|y|\) 次,此时 \(V < B\),然后再加 \(A\),再重复操作。因为 \(A + B \le M + 1\),所以当 \(V < B\) 时 \(V + A\) 一定 \(\le M\)。所以此时可以取到任意 \(V + Ax + By \in [0, M]\) 的值(因为 \(\gcd(A, B) = 1\))。

当 \(A + B \ge M + 2\) 时,不妨先 \(V \gets V \bmod A\)。考虑我们先 \(+ A\),那么此时若不能走到重复的数,只能选择 \(+ A\) 或者 \(- B\)。并且因为 \(A + B > M\),所以至多有一种选择。因此我们如果确定了一开始的操作,之后的操作序列是确定的。

可以证明若一开始的操作确定,那后面不会走到相同的数。设 \(Ax = By\),那么 \(x, y\) 最小正整数解是 \(x = B, y = A\)(因为 \(\gcd(A, B) = 1\))。因为 \(A + B \ge M + 2\),所以在走到之前一定已经形成了环。

还可以证明一开始的操作不同,后面也不会走到相同的数。因为若走到相同的数,另一种走法只能倒着回到起点,矛盾。

所以我们两种走法就是独立的了。现在先讨论一开始选择 \(+ A\)。

考虑采用一开始的走法。先不断 \(V \gets V + A\),直到某一刻 \(V \ge B\),令 \(V \gets V - B\)。设走了 \(n\) 次 \(+ A\),那么走了 \(\left\lfloor\frac{V + nA}{B}\right\rfloor\) 次 \(- B\)。并且因为之后就走不动了,所以 \((V + nA) \bmod B + A \ge M + 1\)。

但是到这一步我们仍不能直接确定最小的 \(n\) 使得它满足上面的条件。考虑设 \(q = \left\lfloor\frac{V + nA}{B}\right\rfloor\),那么 \(qB \le V + nA < (q + 1)B\),并且 \(V + nA - qB \ge M + 1 - A\),所以:

\[\left\lceil\frac{qB - V + M + 1 - A}{A}\right\rceil \le n \le \left\lfloor\frac{qB + B - 1 - V}{A}\right\rfloor \]

发现 \(qB - V + M + 1 - A \le qB + B - 1 - V\),所以我们可以直接 \(r - l + 1\) 求出 \(n\) 的数量。考虑二分最小的 \(q'\) 使得存在一个 \(q \in [0, q']\) 使得上面至少能解出一组解,那么需要满足:

\[\sum\limits_{i = 0}^{q'} \left\lfloor\frac{qB + B - 1 - V}{A}\right\rfloor - \sum\limits_{i = 0}^{q'} \left\lfloor\frac{qB - V + M + 1 - A}{A}\right\rfloor \]

\[= \sum\limits_{i = 0}^{q'} \left\lfloor\frac{qB + B - 1 - V}{A}\right\rfloor - \sum\limits_{i = 0}^{q'} (\left\lfloor\frac{qB - V + M + 1}{A}\right\rfloor - 1) \]

到这里就是一个比较标准的类欧形式了。于是我们可以 \(O(\log M)\) check。总复杂度就是 \(O(T \log^2 M)\) 的。

code
// Problem: F - ±AB
// Contest: AtCoder - AtCoder Regular Contest 127
// URL: https://atcoder.jp/contests/arc127/tasks/arc127_f
// Memory Limit: 1024 MB
// Time Limit: 8000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef __int128 lll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

ll dfs(ll a, ll b, ll c, ll n) {
	if (!a || !n) {
		return (n + 1) * (b / c);
	}
	if (n < 0) {
		return 0;
	}
	if (a >= c || b >= c) {
		return dfs(a % c, b % c, c, n) + (a / c) * (n * (n + 1) / 2) + (b / c) * (n + 1);
	}
	ll m = (a * n + b) / c;
	return m * n - dfs(c, c - b - 1, a, m - 1);
}

inline ll calc(ll p, ll q, ll r, ll n) {
	return dfs(p, r, q, n);
}

void solve() {
	ll A, B, n, m;
	scanf("%lld%lld%lld%lld", &A, &B, &m, &n);
	if (A + B - 1 <= n) {
		printf("%lld\n", n + 1);
		return;
	}
	ll V = m % A;
	ll ans = 1, l = 0, r = n + 5, pos = -1;
	while (l <= r) {
		ll mid = (l + r) >> 1;
		if (calc(B, A, B - 1 - V, mid) - (calc(B, A, n - V, mid) - mid - 1) > 0) {
			pos = mid;
			r = mid - 1;
		} else {
			l = mid + 1;
		}
	}
	ll t = (pos * B - V + n) / A;
	ans += t + (V + t * A) / B;
	swap(A, B);
	l = 0;
	r = n + 5;
	pos = -1;
	while (l <= r) {
		ll mid = (l + r) >> 1;
		if (calc(B, A, B - 1 - V, mid) - (calc(B, A, n - V, mid) - mid - 1) > 0) {
			pos = mid;
			r = mid - 1;
		} else {
			l = mid + 1;
		}
	}
	t = (pos * B - V + n) / A;
	ans += t + (V + t * A) / B;
	printf("%lld\n", ans);
}

int main() {
	int T = 1;
	scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:AtCoder,qB,right,frac,ll,mid,Regular,127,left
From: https://www.cnblogs.com/zltzlt-blog/p/17734325.html

相关文章

  • Atcoder ABC321 笔记
    A-321-likeChecker\(\color{gray}{22}\)直接模拟voidsolve(){intn;cin>>n;intlst=-1;for(inti=n;i;i/=10){intu=i%10;if(u<=lst){cout<<"No"<<endl;......
  • AtCoder Grand Contest 025
    A-DigitsSum按题意模拟即可。#include<iostream>#include<cstdio>usingnamespacestd;constintINF=1061109567;intn;intcalc(intx){intres=0;while(x)res+=x%10,x/=10;returnres;}intmain(){scanf("%d",&......
  • AtCoder Grand Contest 026
    A-ColorfulSlimes2可以发现,对于连续的一段长度为\(m\)的相同的字符,我们可以花费\(\lfloor\frac{m}{2}\rfloor\)的代价将它改为符合要求的。#include<iostream>#include<cstdio>usingnamespacestd;constintN=105;intn;inta[N];intmain(){scanf("%d"......
  • AtCoder Grand Contest 022
    A-DiverseWord如果至少有一个字符没有出现过,只要在原字符串后面加入一个没有出现过的字符中最小的那个字符就好了。如果所有字符都出现过,找到一个尽量靠后的位置\(i\in[1,n)\),使得\(s_i\lts_{i+1}\),最优字符串将\(s_i\)换成\([i+1,n]\)里面比\(s_i\)大的最小的那个......
  • AtCoder Grand Contest 023
    A-Zero-SumRanges令\(s_n=\sum\limits_{i=1}^na_i\),相当于找满足\(l\ler,s_r-s_{l-1}\)的点对\((l,r)\)的个数,直接搞就完事了。#include<iostream>#include<cstdio>#include<unordered_map>usingnamespacestd;constintN=200005;intn;inta[N]......
  • AtCoder Grand Contest 024
    A-Fairness每次操作后\(a_i-b_i=b_{i-1}-a_{i-1}\),对\(k\)的奇偶性讨论一下即可。#include<iostream>#include<cstdio>usingnamespacestd;inta,b,c;longlongk;intmain(){scanf("%d%d%d%lld",&a,&b,&c,&k);if(k%2==0)......
  • AtCoder Grand Contest 021
    A-DigitSum2要么是\(n\)要么是\(n\)的第一位后面加上若干个\(9\)。#include<iostream>#include<cstdio>#include<cmath>usingnamespacestd;longlongn;intcalc(longlongx){if(x==0)return0;intsum=0;while(x)sum+=x......
  • AtCoder Regular Contest 102
    C-TriangularRelationship枚举\(a\bmodk\)的值,\(b\bmodk,c\bmodk\)的值也就确定了,算下贡献就好了。#include<iostream>#include<cstdio>usingnamespacestd;intn,k;intmain(){ scanf("%d%d",&n,&k); longlongans=0; for(inta=0;......
  • AtCoder Regular Contest 103
    C-////如果奇数和偶数出现的颜色的最大值相同一边取最大值和一边取次大值,否则两边都选最大值即可。#include<iostream>#include<cstdio>#include<algorithm>usingnamespacestd;constintN=100005;intn,m;intv[N];intc[N];intmain(){ scanf("%d",&n); for(in......
  • AtCoder Grand Contest 048
    A-atcoder<S枚举操作完的串\(s\)和atcoder相同的前缀长度,算出前面的前缀相同的代价加上当前这位大于atcoder中对应的那一位的代价即为达到当前状态的代价,取个最小值即可。#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;constintN=1......