牛客周赛 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;
}
posted @ 2025-07-13 03:48  Li_Yujia  阅读(8)  评论(0)    收藏  举报