牛客周赛 Round 98题解
A、B、C、D略
E、小红与gcd和sum
题意:
在一个数组中,选择长度为k的子序列,使得\(gcd(a_1 + ... + a_k) * \sum_{i=1}^{k} a_i\)的值最大
思路:
枚举每一个值(gcd)与其所对应的sum最大值相乘的结果
代码
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
const int MAXA = 1'000'000;
vector<int> cnt(MAXA + 1, 0);
int n;
if (!(cin >> n)) return 0;
for (int i = 0, x; i < n; ++i) {
cin >> x;
++cnt[x];
}
int64 answer = 0;
// 枚举每一个可能的 gcd 值 d
for (int d = 1; d <= MAXA; ++d) {
int64 sum = 0;
// 累加所有 d 的倍数
for (int m = d; m <= MAXA; m += d) {
if (cnt[m]) sum += 1LL * m * cnt[m];
}
if (sum) answer = max(answer, 1LL * d * sum);
}
cout << answer << '\n';
return 0;
}
F、小红与天使猫猫酱
题意:
推公式
思路:
经过一系列计算,可得最后要求计算公式:
\[\left(\frac{400(100^n - 1)}{81 \cdot 99} + \frac{280(10^n - 1)}{81 \cdot 9} + \frac{49n}{81})\right)\mod MOD
\]
注意点
①求逆元:
\[x^{-1} \equiv x^{P-2} \pmod{P}
\]
②欧拉降幂:
\[a^k \mod p = a^{k \mod (p-1)} \mod p
\]
③代码中的注释处
代码
#include<bits/stdc++.h>
#define ll long long
#define ce cerr
#define ull unsigned long long
#define lll __int128
using namespace std;
const int inf = 0x3f3f3f3f;
const ll iinf = 1e18;
const int mod = 998244353;
//cin.ignore(std::numeric_limits< streamsize >::max(), '\n');
int t;
ll ksm (ll a, ll b) {
ll res = 1;
while (b) {
if (b & 1) res = res * a % mod;
b >>= 1;
a = a * a % mod;
}
return res;
}
void solve() {
ll n;
cin >> n;
ll one = 400 * (ll)(ksm (100, n % (mod - 1)) + mod - 1) % mod * ksm (81, mod - 2) % mod * ksm (99, mod - 2) % mod;//+mod : 防止变成负数
ll two = 280 * (ll)(ksm (10, n % (mod - 1)) + mod - 1) % mod * ksm (81, mod - 2) % mod * ksm (9, mod - 2) % mod;
ll three = (49 * (n % mod)) % mod * ksm (81, mod - 2) % mod;//49 * n爆ll
ll res = (one + two + three) % mod;
cout << res << "\n";
}
int main() {
ios::sync_with_stdio (false);
cin.tie(NULL);
cout.tie(NULL);
t = 1;
//cin >> t;
while (t --) {
solve();
}
return 0;
}
CF1035C. A Good Problem
题意:
构造一个字典序最小的序列,满足For every \(1 \leq i \leq n\), \(l \leq a_i \leq r\). Additionally, \(a_1 \& a_2 \& \ldots \& a_n = a_1 \oplus a_2 \oplus \ldots \oplus a_n\)
思路:
①n为奇数时,显然全填l一定满足
②n为偶数时,当n=2时,一定不满足。否则只考虑\(a_{n-1}\)和\(a_n\)两位(其他位填l,字典序一定最小),发现当\(a_{n-1}=a_{n}\)时,有\(a_1 \oplus a_2 \oplus \ldots \oplus a_n=0\),故只用考虑如何构造\(a_n\),使得\(a_n \& l = 0\)。设x为l最高位1的位置,发现若\(r>=2^{x+1}\),一定有解。否则一定无解。
另一种判法:
if (__builtin_clzll(l) == __builtin_clzll(r)) {
puts("-1");
return;
}
builtin_clzll:返回前导0个数
以下输出均为2
int x=3;
cout<<32-__builtin_clz(x)<<endl;
long long x=3;
cout<<64-__builtin_clzll(x)<<endl;
代码
#include<bits/stdc++.h>
#define ll long long
#define ce cerr
#define ull unsigned long long
#define lll __int128
using namespace std;
const int inf = 0x3f3f3f3f;
const ll iinf = 1e18;
//cin.ignore(std::numeric_limits< streamsize >::max(), '\n');
int t;
void print (__int128 x) {
if (x < 0) {
x = -x;
cout << "-";
}
if (x > 9) {
print (x / 10);
}
cout << (char) (x % 10 + '0');
}
void solve() {
ll n, l, r, k;
cin >> n >> l >> r >> k;
if (n & 1) cout << l << "\n";
else {
if (n == 2) {
cout << "-1" << "\n";
}else{
int cnt = 0;
for (int i = 63; i >= 0; --i) {
if ((l >> i) & 1) {
cnt = i;
break;
}
}
cnt ++;
__int128 val = (ll)1 << cnt;
if (val > r) {
cout << "-1" << "\n";
}else if (k <= n - 2) {
cout << l << "\n";
}else{
print (val);
cout << "\n";
}
}
}
}
int main() {
ios::sync_with_stdio (false);
cin.tie(NULL);
cout.tie(NULL);
t = 1;
cin >> t;
while (t --) {
solve();
}
return 0;
}