Codeforces Global Round 1 晕阙记

Codeforces Global Round 1 晕阙记

我做这场比赛的时候晕得要死。做这三道题做太久了,rating涨不起来啊!

A

如果愿意的话你可以看做是膜2意义下的运算,写快速幂等各种膜运算。只不过对手速有考验。

B

我题意差点理解不了了。这里讲一下题意:

给你\(m\)条棍子,编号从\(1\)\(m\),有\(n\)个位置的棍子断了。你有无限长的修改带,求你用\(k\)次机会修补棍子,所用修改带的最小长度。允许修补到没断的棍子,允许修改区间重叠。

比赛的时候硬死想不出来,其实挺sb的:

我们贪心地覆盖前\(n-k\)短的区间,剩下的区间直接一个点覆盖即可。

没错,就这么sb且贪心。

我是想不出来。

C

题意当然是看不懂啦!我们打表看看有没有规律。

打表出来的规律就是:如果数字满足\(2^k-1\),那答案是个奇怪的没有规律的答案,否则答案是比它大的第一个\(2^k-1\)

这里就有两种做法:

  1. 脑子不会转弯的做法:可以发现:答案都是当\(b\)取其中的某个因数时得到。所以我们碰到这些\(2^k-1\)的时候,分解因数,\(O(\log n)\)求解。
  2. 比较聪明的人才会的解法:可以发现:这些特殊的数字没多少个啊!我们直接打表不就可以了吗??!!
/*************************************************************************
 @Author: Garen
 @Created Time : Thu 07 Feb 2019 09:15:33 PM CST
 @File Name: A.cpp
 @Description:
 ************************************************************************/
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
#define ll long long
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll gcd(ll x, ll y) {
    return y == 0 ? x : gcd(y, x % y);
}
ll f(ll a) {
    ll res = -INF, idx = -1;
    for(ll b = 1; b < a; b++) {
        ll temp = gcd(a ^ b, a & b);
        //res = std::max(res, gcd(a ^ b, a & b));
        if(temp > res) {
            res = temp; idx = b;
        }
    }
    cout << idx << endl;
    return res;
}
bool check(ll a) {
    ll i = 1;
    while(i <= a) {
        if(i == a) return true;
        i = (i << 1 | 1);
    }
    return false;
}
void baoli(ll a) {
    ll bound = sqrt(a);
    ll ans = -INF;
    for(ll i = 1; i <= bound; i++) {
        if(a % i == 0) {
            if(i != 1) ans = std::max(ans, gcd(a ^ i, a & i));
            if(a / i != i) {
                ll j = a / i;
                if(j != a) ans = std::max(ans, gcd(a ^ j, a & j));
            }
        }
    }
    if(ans == -INF) ans = 1;
    cout << ans << endl;
}
int main() {
    ll q; cin >> q;
    while(q--) {
        ll a; cin >> a;
        if(check(a)) {
            baoli(a);
        } else {
            ll i = 1;
            while(i <= a) i = (i << 1 | 1);
            cout << i << endl;
        }
    }
    /*
    for(ll a = 1; a <= 10000; a++) {
        cout << "f(" << a << ") = ";
        if(check(a)) {
            baoli(a);
        } else {
            ll i = 1;
            while(i <= a) i = (i << 1 | 1);
            cout << i << endl;
        }
    }
    */
    return 0;
}

E

这里立一个flag。听说不难的样子。

猜你喜欢

转载自www.cnblogs.com/Garen-Wang/p/10403679.html