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情况:
大概是这几种,讨论一下即可。
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
留坑待补