AtCoder Regular Contest 158 题解

题面:https://atcoder.jp/contests/arc158/tasks_print

A - +3 +5 +7

\(+3,+5,+7\) 可以在不改变相对位置的情况下都 \(-5\),即变成 \(-2,+0,+2\),发现和不变,可以得出最后的数的值 \(x=\dfrac{a+b+c}{3}\),如果 \(x\) 不是整数就无解。发现答案为 \(\dfrac{|a-x|+|b-x|+|c-x|}{4}\),如果不是整数也无解。

注:计算过程中有任何不满足实际意义的都算无解。

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
#define rep(i, a, b) for(int i = a;i <= b; ++ i)
#define per(i, b, a) for(int i = b;i >= a; -- i)
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
#define int long long
namespace fastIO {
	template < typename T > void read (T &x) {x = 0; T flag = 1; char c = getchar (); for ( ; c < '0' || c > '9' ; c = getchar ()) flag = (c == '-') ? -1 : flag; for ( ; c >= '0' && c <= '9' ; c = getchar ()) x = (x << 1) + (x << 3) + (c ^ 48); x *= flag;}
	template < typename T, typename ...T1 > void read (T &x, T1 &...x1) {read (x); read (x1...);}
	template < typename T > void write (T x) {if (x < 0) {x = -x; putchar ('-');} if (x / 10) {write (x / 10);} putchar (x % 10 + '0');}
	template < typename T > void writesp (T x) {write (x); putchar (' ');}
	template < typename T > void writeln (T x) {write (x); putchar ('\n');}
}
using namespace fastIO;
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
signed main () {
	int T; read (T);
	while (T --) {
		int a, b, c;
		read (a, b, c);
		int avg = (a + b + c) / 3;
		if ((a + b + c) % 3) {
			puts ("-1");
			continue;
		}
		int da = avg - a;
		int db = avg - b;
		int dc = avg - c;
		if (da + db + dc) {
			puts ("-1");
			continue;
		}
		if (abs (da) & 1) {puts ("-1"); continue;}
		if (abs (db) & 1) {puts ("-1"); continue;}
		if (abs (dc) & 1) {puts ("-1"); continue;}
		da = max (da, -da);
		db = max (db, -db);
		dc = max (dc, -dc);
		da /= 2, db /= 2, dc /= 2;
		if ((da + db + dc) & 1) {
			puts ("-1");
			continue;
		}
		writeln ((da + db + dc) / 2);
	}
	return 0;
}

B - Sum-Product Ratio

发现 \(x\) 只可能从 \(a\) 中最大的三个和最小的三个取,枚举即可。

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
#define rep(i, a, b) for(int i = a;i <= b; ++ i)
#define per(i, b, a) for(int i = b;i >= a; -- i)
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
#define int long long
namespace fastIO {
	template < typename T > void read (T &x) {x = 0; T flag = 1; char c = getchar (); for ( ; c < '0' || c > '9' ; c = getchar ()) flag = (c == '-') ? -1 : flag; for ( ; c >= '0' && c <= '9' ; c = getchar ()) x = (x << 1) + (x << 3) + (c ^ 48); x *= flag;}
	template < typename T, typename ...T1 > void read (T &x, T1 &...x1) {read (x); read (x1...);}
	template < typename T > void write (T x) {if (x < 0) {x = -x; putchar ('-');} if (x / 10) {write (x / 10);} putchar (x % 10 + '0');}
	template < typename T > void writesp (T x) {write (x); putchar (' ');}
	template < typename T > void writeln (T x) {write (x); putchar ('\n');}
}
using namespace fastIO;
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
int n, a[200005], pos[200005], neg[200005], np, nn;
long double mx, mn;
inline void upd (long double tmp) {
	if (mx - tmp < 1e-18) mx = tmp;
	if (mn - tmp > 1e-18) mn = tmp;
}
inline int pos_up_sum (int x) {int s = 0; rep (i, 1, x) s += pos[np - i + 1]; return s;}
inline int pos_down_sum (int x) {int s = 0; rep (i, 1, x) s += pos[i]; return s;}
inline int neg_up_sum (int x) {int s = 0; rep (i, 1, x) s += neg[nn - i + 1]; return s;}
inline int neg_down_sum (int x) {int s = 0; rep (i, 1, x) s += neg[i]; return s;}
inline int pos_up_pd (int x) {int s = 1; rep (i, 1, x) s *= pos[np - i + 1]; return s;}
inline int pos_down_pd (int x) {int s = 1; rep (i, 1, x) s *= pos[i]; return s;}
inline int neg_up_pd (int x) {int s = 1; rep (i, 1, x) s *= neg[nn - i + 1]; return s;}
inline int neg_down_pd (int x) {int s = 1; rep (i, 1, x) s *= neg[i]; return s;}
signed main () {
	read (n);
	rep (i, 1, n) read (a[i]);
	rep (i, 1, n) {
		if (a[i] > 0) pos[++ np] = a[i];
		else neg[++ nn] = a[i];
	}
	sort (pos + 1, pos + 1 + np);
	sort (neg + 1, neg + 1 + nn);
	mx = -1e100;
	mn = 1e100;
	rep (i, 0, 3) {
		int j = 3 - i;
		if (np >= i && nn >= j) {
			rep (k1, 0, i) {
				rep (k2, 0, j) {
					upd ((long double) (pos_up_sum (k1) + pos_down_sum (i - k1) + neg_up_sum (k2) + neg_down_sum (j - k2)) / (long double) (pos_up_pd (k1) * pos_down_pd (i - k1) * neg_up_pd (k2) * neg_down_pd (j - k2)));			
				}
			}
		}
	}
	printf ("%.12Lf\n%.12Lf\n", mn, mx);
	return 0;
}

C - All Pair Digit Sums

突破口:每次进位会将数位和减去 \(9\)

\(g(a,b)\) 为计算 \(a+b\) 时的进位次数。

则:\(f(a+b)=f(a)+f(b)-9\times g(a,b)\)

至于 \(g\) 函数,我们可以将每一位拆开,对每一位 \(k=0,1,\dots\),如果 \(a \bmod 10^{k+1}+b\bmod 10^{k+1} \geq 10^{k+1}\),则进位次数加 \(1\),答案减去 \(9\)

具体实现用二分可以做到 \(O(16 n \log n)\)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
#define int long long
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
const int N = 200005;
int n, a[N], ans;
struct qwq {
	int pri;
	int val;
} b[N];
inline bool cmp (qwq p1, qwq p2) {
	return p1.pri < p2.pri;
}
inline int sum (int x) {
	int res = 0;
	while (x) {
		res += x % 10;
		x /= 10;
	}
	return res;
}
signed main () {
	scanf ("%lld", &n);
	for (int i = 1;i <= n; ++ i) scanf ("%lld", &a[i]), ans += sum (a[i]);
	ans *= 2 * n;
	int tmp = 1;
	for (int i = 0;i <= 15; ++ i) {
		tmp *= 10;
		for (int j = 1;j <= n; ++ j) b[j].val = a[j], b[j].pri = a[j] % tmp;
		sort (b + 1, b + 1 + n, cmp);
		for (int j = 1;j <= n; ++ j) {
			if (b[n].pri + b[j].pri < tmp) ;
			else {
				int L = 1, R = n;
				while (R - L > 1) {
					int mid = L + R >> 1;
					if (b[mid].pri + b[j].pri >= tmp) R = mid;
					else L = mid;
				}
				if (b[L].pri + b[j].pri >= tmp) ans -= 9 * (n - L + 1);
				else ans -= 9 * (n - R + 1);
			}
		}
	}
	printf ("%lld\n", ans);
	return 0;
}

D - Equation

我们考虑随机答案。

每次随机出 \(a,b,c\),成功的概率在 \(p\) 很大的时候微乎其微。

考虑调整 \(a,b,c\),设 \(f=(a+b+c)(a^n+b^n+c^n)(a^{2n}+b^{2n}+c^{2n}),g=a^{3n}+b^{3n}+c^{3n}\)

我们调整目标就是让 \(f=g\)

考虑将 \(a,b,c\) 都乘以 \(t\)

\(f',g'\) 为新的 LHS & RHS, 则 \(f'=t^{3n+1}f,g'=t^{3n}g\)

\(f'=g'\),则:\(t=\dfrac{g}{f}\),只要满足 \(f\bmod p,g \bmod p>0\) 即可。

这样一次成功的概率就大大增加了。

感觉题目的一切都是为题解准备的。(要不 \(p\) 是质数)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
#define int long long
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
int n, p;
inline int pow_mod (int a, int b, int p) {
	int res = 1;
	while (b) {
		if (b & 1) res = res * a % p;
		b >>= 1;
		a = a * a % p; 
	}
	return res;
}
signed main () {
	int _;
	scanf ("%lld", &_);
	while (_ --) {
		scanf ("%lld %lld", &n, &p);
		while (true) {
			int x, y, z;
			x = randomly (1, p - 1);
			if (x + 1 >= p) continue;  
			y = randomly (x + 1, p - 1);
			if (y + 1 >= p) continue;
			z = randomly (y + 1, p - 1);
			int xn = pow_mod (x, n, p);
			int yn = pow_mod (y, n, p);
			int zn = pow_mod (z, n, p);
			int x2n = xn * xn % p;
			int y2n = yn * yn % p;
			int z2n = zn * zn % p;
			int x3n = xn * x2n % p;
			int y3n = yn * y2n % p;
			int z3n = zn * z2n % p;
			int LHS = (x + y + z) % p * (xn + yn + zn) % p * (x2n + y2n + z2n) % p;
			int RHS = (x3n + y3n + z3n) % p;
			if (LHS == RHS) {
				printf ("%lld %lld %lld\n", x, y, z);
				break;
			}
			if (LHS && RHS) {
				int t = RHS * pow_mod (LHS, p - 2, p) % p;
				vector < int > qwq;
				qwq.clear ();
				qwq.push_back (x * t % p);
				qwq.push_back (y * t % p);
				qwq.push_back (z * t % p);
				sort (qwq.begin (), qwq.end ());
				printf ("%lld %lld %lld\n", qwq[0], qwq[1], qwq[2]);
				break;
			}
		}
	}
	return 0;
}
posted @ 2023-03-20 23:08  CountingGroup  阅读(67)  评论(0编辑  收藏  举报