Codeforces Round 860 (Div. 2)
Posted RB16B
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round 860 (Div. 2)相关的知识,希望对你有一定的参考价值。
https://codeforces.com/contest/1798/problems
A. Showstopper
考虑将 \\(\\max(a_i,b_i)\\) 全都交换到 \\(b_i\\),那么 \\(a_i\\) 就是 \\(\\min(a_i,b_i)\\)。
只需要判定:
是否满足即可。
正确性显然。
#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 _;
int a[105], b[105], n;
signed main ()
scanf ("%d", &_);
while (_ --)
scanf ("%d", &n);
for (int i = 1;i <= n; ++ i) scanf ("%d", &a[i]);
for (int i = 1;i <= n; ++ i) scanf ("%d", &b[i]);
for (int i = 1;i <= n; ++ i)
if (a[i] <= b[i]) ;
else swap (a[i], b[i]);
int mxa = 0, mxb = 0;
for (int i = 1;i <= n; ++ i)
mxa = max (mxa, a[i]);
mxb = max (mxb, b[i]);
if (a[n] == mxa && b[n] == mxb) printf ("Yes\\n");
else printf ("No\\n");
return 0;
B. Three Sevens
可以发现,第 \\(i\\) 天的 Winner 一定是没有在 \\(i+1\\sim m\\) 天中的参赛者,所以只需要将 \\(a_i\\) 中在 \\(a_i+1,a_i+2,\\dots,a_m\\) 中出现过的数去掉,如果为空就无解,不然就从操作过的 \\(a_i\\) 中随便选一个作为 \\(p_i\\)。
具体可以用一个桶维护每个数出现次数。
#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 mp[50005], m, n[50005], winner[50005];
vector < int > seq[50005];
signed main ()
int _;
scanf ("%d", &_);
while (_ --)
scanf ("%d", &m);
for (int i = 1;i <= m; ++ i)
scanf ("%d", &n[i]);
for (int j = 1;j <= n[i]; ++ j)
int u;
scanf ("%d", &u);
seq[i].push_back (u);
mp[u] ++;
int ok = 1;
for (int i = 1;i <= m; ++ i)
winner[i] = -1;
for (int j = 1;j <= n[i]; ++ j) mp[seq[i][j - 1]] --;
for (int j = 1;j <= n[i]; ++ j)
if (!mp[seq[i][j - 1]])
winner[i] = seq[i][j - 1];
break;
if (winner[i] == -1) ok = 0;
for (int i = 1;i <= m; ++ i)
for (int j = 1;j <= n[i]; ++ j) seq[i].pop_back ();
if (ok)
for (int i = 1;i <= m; ++ i) printf ("%d ", winner[i]);
printf ("\\n");
else printf ("-1\\n");
return 0;
C. Candy Store
可以发现,\\([L,R]\\) 可以满足条件当且仅当 \\(\\displaystyle \\gcd\\limits_i=L^R(a_ib_i) \\bmod \\textlcm_i=L^R(b_i)=0\\)。
静态查询 \\(\\gcd,\\textlcm\\) 可以使用 ST 表预处理。
注意这个 \\(\\textlcm\\) 会爆 long long,记得对 \\(10^13+1\\) 进行取 min 操作,别爆了。
#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;
inline int gcd (int a, int b) return b == 0 ? a : gcd (b, a % b);
inline int lcm (int a, int b)
if (a > 1e13 || b > 1e13) return 1e13 + 1;
int LHS = a / gcd (a, b);
int RHS = 1e13 / b;
if (LHS > RHS) return 1e13 + 1;
int awa = LHS * b;
if (awa > 1e13) awa = 1e13 + 1;
return awa;
int lc[200005][21], gc[200005][21], lg[200005], f[200005], early[200005];
inline int lcm_b (int l, int r)
int k = lg[r - l + 1];
return lcm (lc[l][k], lc[r - (1 << k) + 1][k]);
inline int gcd_ab (int l, int r)
int k = lg[r - l + 1];
return gcd (gc[l][k], gc[r - (1 << k) + 1][k]);
int n, a[200005], b[200005];
signed main ()
int _;
scanf ("%lld", &_);
while (_ --)
scanf ("%lld", &n);
for (int i = 1;i <= n; ++ i) scanf ("%lld %lld", &a[i], &b[i]);
lg[0] = -1;
for (int i = 1;i <= n; ++ i) lg[i] = lg[i / 2] + 1;
for (int i = 1;i <= n; ++ i) lc[i][0] = b[i], gc[i][0] = a[i] * b[i];
for (int j = 1;j <= 19; ++ j)
for (int i = 1;i + (1 << j) - 1 <= n; ++ i)
lc[i][j] = lcm (lc[i][j - 1], lc[i + (1 << (j - 1))][j - 1]);
gc[i][j] = gcd (gc[i][j - 1], gc[i + (1 << (j - 1))][j - 1]);
for (int i = 1;i <= n; ++ i)
int L = 1, R = i;
while (R - L > 1)
int mid = L + R >> 1;
if (gcd_ab (mid, i) % lcm_b (mid, i) != 0) L = mid;
else R = mid;
if (gcd_ab (L, i) % lcm_b (L, i) == 0) early[i] = L;
else early[i] = R;
f[0] = 0;
f[1] = 1;
for (int i = 1;i <= n; ++ i) f[i] = f[early[i] - 1] + 1;
printf ("%lld\\n", f[n]);
return 0;
D. Shocking Arrangement
特别的,全为 \\(0\\) 的序列肯定无解(至于为什么自己算)。
对于剩下的序列,因为 \\(\\displaystyle \\sum_i=1^na_i=0\\),所以 \\(\\max\\limits_i=1^na_i>0,\\min\\limits_i=1^na_i<0\\)。
进一步推出:\\(\\max\\limits_i=1^na_i-\\min\\limits_i=1^na_i>\\max\\limits_i=1^n|a_i|\\)(因为有正有负,所以极差肯定是两个绝对值大于 \\(0\\) 的数的绝对值之和)。
所以我们只需要保证每个子序列的和的绝对值都不超过 \\(a\\) 中绝对值最大的数的绝对值。
考虑每次 push_back,如果当前和 \\(\\leq 0\\),就加上最大的正数,否则就加上最小的负数。(因为和为 \\(0\\) 所以肯定会有加的数)
这样做一定不会爆掉,前缀和一减也不会爆。
#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 a[300005], n;
signed main ()
int _;
scanf ("%lld", &_);
while (_ --)
scanf ("%lld", &n);
int os = 0;
for (int i = 1;i <= n; ++ i) scanf ("%lld", &a[i]), os += (a[i] == 0);
sort (a + 1, a + 1 + n);
if (os == n)
printf ("No\\n");
continue;
printf ("Yes\\n");
int L = 1, R = n, sum = 0, num = n;
while (num --)
if (sum <= 0)
printf ("%lld ", a[R]);
sum += a[R];
R --;
else
printf ("%lld ", a[L]);
sum += a[L];
L ++;
printf ("\\n");
return 0;
以上是关于Codeforces Round 860 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #774 (Div. 2)
Codeforces Round #808 (Div. 1)(A~C)
Codeforces Round #717 (Div. 2)
Codeforces Round #784 (Div. 4)