Codeforces Round 613(div 2)

Round 613(div 2)

A

题面

思路

显然,\(ans = L + R + 1 = n + 1\)

Code

#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
const int maxn = 1e5+10;
int n;
int l = 0, r = 0;
char str[maxn];
 
int main() {
    scanf("%d%s", &n, str);
    for (int i = 0; str[i]; ++i) {
        if(str[i] == 'L') ++l;
        else ++r;
    }
    printf("%d\n", r + l + 1);
 
    return 0;
}

B

题面

思路

满足条件的方法只有一个,\(a_1 + a_2 + \dots + a_n\) 的值是最大的,因此只需判断从两端向中间的连续和是否小于零即可。

Code

#include <bits/stdc++.h>
 
using namespace std;
 
const int maxn = 1e5+10;
typedef  long long ll;
int n;
ll a[maxn];
 
int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        ll l = 0 , r = 0;
        bool fg = false;
        for (int i = 1; i <= n; ++i)
            scanf("%lld", a+i);
        for (int i = 1; i <= n; ++i) {
            l += a[i];
            r += a[n - i + 1];
            if(l <= 0 || r <= 0) fg = 1;
        }
        puts(fg? "NO": "YES");
    }
 
    return 0;
}

C

题面

思路

易得:\(a \times b = lcm(a, b) \times gcd(a, b)\)

即:\(a \times b = X \times gcd(a, b)\)

故:$X = \frac{a\times b}{gcd(a, b)} $

\(\frac{a}{gcd(a, b)}\)\(b\) 互质,因此只需要根号枚举X的因数,即可。

Code

#include <bits/stdc++.h>
 
using namespace std;
 
const int maxn = 1e5+10;
typedef  long long ll;
const ll inf = 1e18+7;
int n;
ll x;
 
 
int main() {
    scanf("%lld", &x);
    if(x == 1) return puts("1 1"), 0;
    ll ans = inf;
    for (ll i = 1; i * i < x; ++i) {
        if(x%i == 0 && __gcd(i, x/i) == 1) {
            ans = x/i;
        }
    }
    printf("%lld %lld\n", x/ans, ans);
 
    return 0;
}

D

题面

思路

以二进制的方式看每一个数。

若第 \(i\) 位上均为 1 或者均为 0,则与 X 异或后该位为 0,否则,该位为 1。

需要讨论的地方在于,该位为 1 时, X 的 第 i 位为 0 还是 1,因此可以将数组分成两类递归一下,选择较小的那个返回。

Code

#include <bits/stdc++.h>
 
using namespace std;
 
const int maxn = 1e5+10;
typedef  long long ll;
const ll inf = (1ll<<31)-1;
int n;
 
ll calc(vector<int> &c, int cur) {
    if(c.empty() || cur < 0) return 0ll;
    int now = 1 << cur;
    vector<int> on, off;
    for (auto v: c) {
        if(v & now) on.push_back(v);
        else off.push_back(v);
    }
    if(on.empty()) return calc(off, cur-1);
    if(off.empty()) return calc(on, cur-1);
    return min(calc(on, cur-1), calc(off, cur-1)) + now;
}
 
int main() {
    scanf("%lld", &n);
    vector<int> a;
    for (int x, i = 1; i <= n; ++i) {
        scanf("%d", &x);
        a.push_back(x);
    }
    printf("%lld\n", calc(a, 30));
    return 0;
}

E

题面

思路

合并后的右端点数即为线段数,因此可以处理右端点。

讨论Case情况:

image-20200121115400590

大概是这几种,讨论一下即可。

Code

#include <bits/stdc++.h>
 
using namespace std;
 
typedef pair<int, int> pii;
const int maxn = 1e6+10;
const int maxm = 1e6+10;
 
int n, ans[maxn];
pii a[maxn];
 
void solve() {
    scanf("%d", &n);
    for (int l, r, i = 1; i <= n; ++i) {
        scanf("%d%d", &l, &r);
        a[i*2-1] = {l, -i};
        a[i<<1] = {r, i};
        ans[i] = 0;
    }
    sort(a + 1, a + 1 + 2 * n);
    multiset<int> st;
    int group = 0;
    for (int i = 1; i <= 2*n; ++i) {
        if (a[i].second < 0) st.insert(-a[i].second);
        else st.erase(st.find(a[i].second));
        if(st.empty()) ++group;
        else if(st.size() == 1) {
            if(a[i].second > 0 && a[i+1].second < 0 && a[i].first < a[i+1].first) ++ans[*st.begin()];
            if(a[i].second < 0 && a[i+1].second > 0) --ans[*st.begin()];
        }
    }
    int res = -n;
    for (int i = 1; i <= n; ++i) res = max(res, ans[i]);
    printf("%d\n", group + res);
}
 
int main() {
    int T;
    scanf("%d", &T);
    while(T--)
        solve();
 
    return 0;
}

F

留坑待补

posted @ 2020-01-21 11:55  Acerkoo  阅读(193)  评论(0编辑  收藏  举报