A 这是一个特别难的题目
直接输出答案,复杂度
let's go
B 相识
贪心的考虑每一位都为
,即枚举所有的
,然后判断结果是否合法即可,复杂度 )
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define endl '\n'
constexpr i64 Mod = 1000000007;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
void solve() {
i64 n;
cin >> n;
int ans = 0;
static const i64 inf = 1e18;
for (int i = 1; i < 64; i++) {
i64 b = (1LL << i) - 1;
i64 x = n + b, y = n - b;
if (x > 0 && x <= inf || y > 0 && y <= inf) {
ans = max(ans, i);
}
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
C 散步
暴力 DFS 一下即可,复杂度不超过
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define endl '\n'
constexpr i64 Mod = 1000000007;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
class Z {
using i64 = long long;
static const i64 Mod = 20130744;
public:
i64 num;
Z() = default;
Z(i64 _num) : num((_num % Mod + Mod) % Mod) {}
i64 val() const {
return num;
}
Z &operator = (i64 b) {
return *this = Z(b);
}
friend bool operator < (Z a, Z b) {
return a.num < b.num;
}
friend bool operator >(Z a, Z b) {
return a.num > b.num;
}
friend bool operator <=(Z a, Z b) {
return a.num <= b.num;
}
friend bool operator>=(Z a, Z b) {
return a.num >= b.num;
}
friend bool operator==(Z a, Z b) {
return a.num == b.num;
}
friend Z operator + (Z a, Z b) {
return Z((a.num + b.num) % Mod);
}
friend Z &operator += (Z &a,Z b) {
return a = a + b;
}
friend Z operator + (Z a, i64 b) {
return a + Z(b);
}
friend Z &operator += (Z &a, i64 b) {
return a = a + b;
}
friend Z &operator ++ (Z &a) {
return a += 1;
}
friend Z operator ++ (Z &a, int) {
Z copy(a);
a += 1;
return copy;
}
friend Z operator - (Z a, Z b) {
return Z(((a.num - b.num) % Mod + Mod) % Mod);
}
friend Z &operator -= (Z &a, Z b) {
return a = a - b;
}
friend Z operator - (Z a, i64 b) {
return a - Z(b);
}
friend Z &operator -= (Z &a, i64 b) {
return a = a - b;
}
friend Z &operator -- (Z &a) {
return a -= 1;
}
friend Z operator -- (Z &a, int) {
Z copy(a);
a -= 1;
return copy;
}
friend Z operator * (Z a, Z b) {
return Z((long long)a.num * b.num % Mod);
}
friend Z &operator *= (Z &a, Z b) {
return a = a * b;
}
friend Z operator * (Z a, i64 b) {
return a * Z(b);
}
friend Z &operator *= (Z &a, i64 b) {
return a = a * b;
}
Z inv() {
i64 ans = 1;
i64 a = num;
i64 b = Mod - 2;
while (b) {
if (b & 1) ans = ans * a % Mod;
a = a * a % Mod;
b >>= 1;
}
return Z(ans);
}
friend Z operator / (Z a, Z b) {
return a * b.inv();
}
friend Z &operator /= (Z &a, Z b) {
return a = a / b;
}
friend Z operator / (Z a, i64 b) {
return a / Z(b);
}
friend Z &operator /= (Z &a, i64 b) {
return a = a / b;
}
friend std::istream &operator>>(std::istream &is, Z &a) {
int v;
is >> v;
a = Z(v);
return is;
}
friend std::ostream &operator<<(std::ostream &os, const Z &a) {
return os << a.val();
}
};
void solve() {
int n, m;
cin >> n >> m;
vector<vector<int>> adj(n + 1);
map<pair<int, int>, int> mp;
for (int i = 0; i < m; i++) {
int x, y, z;
cin >> x >> y >> z;
mp[{x, y}] += z;
mp[{y, x}] += z;
adj[x].emplace_back(y);
adj[y].emplace_back(x);
}
Z ans = 0;
auto dfs = [&](auto &&self, int u, int v, Z add) -> void {
if (u == n) {
ans += add;
return;
}
for (auto c: adj[u]) {
if (c == v || c < u) {
continue;
}
self(self, c, u, add * mp[{c, u}]);
}
};
dfs(dfs, 1, -1, Z(1));
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
D 看书
暴力计算锐角和非锐角的个数,每个锐角三角形对锐角的贡献数量为
,直角三角形和钝角三角形对锐角的贡献数量为
。设锐角的数量为
,钝角的数量为
,答案即为
。
对每个点做极角排序,然后用 Two Pointers 的经典方法,即可做到
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define endl '\n'
constexpr i64 Mod = 1000000007;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
void solve() {
int n;
cin >> n;
vector<double> x(n + 1), y(n + 1);
for (int i = 1; i <= n; i++) {
cin >> x[i] >> y[i];
}
static const double pi = acos(-1.0);
vector<double> ang(n * 2 + 1);
i64 u = 0, v = 0;
for (int i = 1; i <= n; i++) {
int cnt = 0;
for (int j = 1; j <= n; j++) {
if (i == j) {
continue;
}
ang[++cnt] = atan2(y[i] - y[j], x[i] - x[j]);
if (ang[cnt] < 0) {
ang[cnt] += 2. * pi;
}
}
sort(ang.begin() + 1, ang.begin() + cnt + 1);
for (int j = 1; j <= cnt; j++) {
ang[j + cnt] = ang[j] + 2. * pi;
}
i64 l = 1, r = 1;
i64 len = 1;
for (int j = 1; j <= cnt; j++) {
while (r < 2LL * cnt && ang[r] - ang[j] < pi) {
r++;
}
while (l < 2LL * cnt && ang[l] - ang[j] < 0.5 * pi) {
l++;
}
while (len < 2LL * cnt && ang[j] == ang[len]) {
len++;
}
u += l - len;
v += r - l;
}
}
i64 ans = (u - 2LL * v) / 3;
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
E 赏月
结论题,答案为
,推断不难。复杂度 )
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define endl '\n'
constexpr i64 Mod = 1000000007;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
void solve() {
double n, p, q;
cin >> n >> p >> q;
n /= 100;
p /= 100;
q /= 100;
p = 1. - p;
q = 1. - q;
double ans = 1. / (n * p * q);
cout << fixed << setprecision(10);
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
F 礼物
暴力枚举所有的选购礼物的情况,然后判断合法性即可,复杂度
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define endl '\n'
constexpr i64 Mod = 1000000007;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
void solve() {
int n, m;
cin >> n >> m;
vector<int> v(n), w(n);
for (int i = 0; i < n; i++) {
cin >> v[i];
}
for (int i = 0; i < n; i++) {
cin >> w[i];
}
auto check = [&](int u) -> bool {
while (u) {
int x = u % 10;
if (x != 0 && x != 1 && x != 3 && x != 7 && x != 9) {
return false;
}
u /= 10;
}
return true;
};
int ans = 0;
auto dfs = [&](auto &&self, int u, int cur, int V) -> void {
if (check(cur) && V <= m){
ans = max(ans, cur);
}
if (u == n) {
return;
}
self(self, u + 1, cur + w[u], V + v[u]);
self(self, u + 1, cur, V);
};
dfs(dfs, 0, 0, 0);
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
G 开心度
二分开心度,用 Segment tree 维护区间加减法,然后判断是否存在连续的长度至少为
的和为非负数的区间即可,变成了一个简单的 DP 问题。复杂度
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define endl '\n'
constexpr i64 Mod = 1000000007;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class Info, class Tag>
struct LazySegmentTree {
const int n;
std::vector<Info> info;
std::vector<Tag> tag;
LazySegmentTree(int n) : n(n), info(4 << std::__lg(n)), tag(4 << std::__lg(n)) {}
LazySegmentTree(std::vector<Info> init) : LazySegmentTree(init.size()) {
std::function<void(int, int, int)> build = [&](int p, int l, int r) {
if (r - l == 1) {
info[p] = init[l];
return;
}
int m = (l + r) / 2;
build(2 * p, l, m);
build(2 * p + 1, m, r);
pull(p);
};
build(1, 0, n);
}
void pull(int p) {
info[p] = info[2 * p] + info[2 * p + 1];
}
void apply(int p, const Tag &v) {
info[p].apply(v);
tag[p].apply(v);
}
void push(int p) {
apply(2 * p, tag[p]);
apply(2 * p + 1, tag[p]);
tag[p] = Tag();
}
void modify(int p, int l, int r, int x, const Info &v) {
if (r - l == 1) {
info[p] = v;
return;
}
int m = (l + r) / 2;
push(p);
if (x < m) {
modify(2 * p, l, m, x, v);
} else {
modify(2 * p + 1, m, r, x, v);
}
pull(p);
}
void modify(int p, const Info &v) {
modify(1, 0, n, p, v);
}
Info rangeQuery(int p, int l, int r, int x, int y) {
if (l >= y || r <= x) {
return Info();
}
if (l >= x && r <= y) {
return info[p];
}
int m = (l + r) / 2;
push(p);
return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
}
Info rangeQuery(int l, int r) {
return rangeQuery(1, 0, n, l, r);
}
void rangeApply(int p, int l, int r, int x, int y, const Tag &v) {
if (l >= y || r <= x) {
return;
}
if (l >= x && r <= y) {
apply(p, v);
return;
}
int m = (l + r) / 2;
push(p);
rangeApply(2 * p, l, m, x, y, v);
rangeApply(2 * p + 1, m, r, x, y, v);
pull(p);
}
void rangeApply(int l, int r, const Tag &v) {
return rangeApply(1, 0, n, l, r, v);
}
void half(int p, int l, int r) {
if (info[p].act == 0) {
return;
}
if ((info[p].min + 1) / 2 == (info[p].max + 1) / 2) {
apply(p, {-(info[p].min + 1) / 2});
return;
}
int m = (l + r) / 2;
push(p);
half(2 * p, l, m);
half(2 * p + 1, m, r);
pull(p);
}
void half() {
half(1, 0, n);
}
};
struct Tag {
double add = 0;
void apply(Tag t) {
add += t.add;
}
};
struct Info {
double Act = 1;
double Sum = 0;
void apply(Tag t) {
Sum += 1. * Act * t.add;
}
};
Info operator+(Info a, Info b) {
Info c;
c.Sum = a.Sum + b.Sum;
c.Act = a.Act + b.Act;
return c;
}
void solve() {
int n;
cin >> n;
vector<Info> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i].Sum;
}
LazySegmentTree<Info, Tag> seg(a);
static const double eps = 1e-4;
auto check = [&](double u) -> bool {
seg.rangeApply(0, n, Tag{-u});
vector<array<double, 2>> dp;
dp.assign(n, {});
dp[0][0] = seg.rangeQuery(0, 1).Sum;
dp[0][1] = -1e9;
for (int i = 1; i < n; i++) {
dp[i][0] = seg.rangeQuery(i, i + 1).Sum;
dp[i][1] = max(dp[i - 1][0], dp[i - 1][1]) + seg.rangeQuery(i, i + 1).Sum;
}
seg.rangeApply(0, n, Tag{u});
for (int i = 1; i < n; i++) {
if (dp[i][1] >= eps) {
return true;
}
}
return false;
};
double l = 0, r = 10001.0;
while (l <= r) {
double mid = (l + r) / 2;
if (check(mid)) {
l = mid + 0.01;
} else {
r = mid - 0.01;
}
}
cout << fixed << setprecision(1);
cout << l << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
H 旅行
根据要求自定义快排即可,复杂度
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define endl '\n'
constexpr i64 Mod = 1000000007;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
struct g {
int x, y;
int z;
int id;
int vis;
};
void solve() {
int n, m;
cin >> n >> m;
vector<g> v(n);
for (int i = 0; i < n; i++) {
cin >> v[i].x;
}
for (int i = 0; i < n; i++) {
cin >> v[i].y;
}
for (int i = 0; i < n; i++) {
v[i].z = v[i].x + v[i].y;
v[i].id = i + 1;
v[i].vis = v[i].x != 0 && v[i].y != 0;
}
auto cmp = [&](struct g a, struct g b) -> bool {
if (a.vis != b.vis) {
return a.vis > b.vis;
}
if (a.z == b.z) {
return a.id < b.id;
} else {
return a.z > b.z;
}
return true;
};
sort(v.begin(), v.end(), cmp);
i64 ans = 0;
for (int i = 0; i < m; i++) {
ans += v[i].id;
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
I 奇妙的缘分
暴力统计即可,复杂度不超过
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define endl '\n'
constexpr i64 Mod = 1000000007;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
void solve() {
int n, m;
cin >> n >> m;
map<int, int> x, y;
for (int i = 0; i < n; i++) {
int a = 0, b = 0;
string s;
cin >> s;
int pos = -1;
for (int j = 0; j < s.size(); j++) {
if (s[j] == '/') {
pos = j;
break;
}
}
for (int j = 0; j < pos; j++) {
a = a * 10 + s[j] - '0';
}
for (int j = pos + 1; j < s.size(); j++) {
b = b * 10 + s[j] - '0';
}
if (a == 1 || a == 3 || a == 5 || a == 7 || a == 8 || a == 10 || a == 12) {
if (b < 0 || b > 31) {
continue;
}
} else if (a == 2) {
if (b < 0 || b > 29) {
continue;
}
} else if (a == 4 || a == 6 || a == 9 || a == 11) {
if (b < 0 || b > 30) {
continue;
}
} else {
continue;
}
int u = to_string(b).size();
x[a * pow(10, u) + b]++;
}
for (int i = 0; i < n; i++) {
int a;
cin >> a;
y[a]++;
}
int ans = 0;
for (auto &[l, r]: x) {
if (y.contains(l)) {
ans += min(r, y[l]);
y[l] -= min(r, y[l]);
}
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
J 爵士
将
转换成
和
,设
表示长度为
,异或和为
的数的个数,分别预处理出不考虑前导
和考虑前导
的情况下的
数组。
然后考虑计算
上的问题,设
的长度为
,那么对于所有的
,其贡献都是完整的,直接累加即可。
只需考虑长度为
的情况,从高位到低位枚举,设此前已经枚举了
位数,这些数的异或和为
,分两种情况讨论:
1. 当前位选择的数
小于
上的对应数位的数,那么对答案的贡献为
,计算结束
2. 否则,置
,继续往下枚举
上述操作可以通过一次 DFS 计算,此外还注意一些细节问题。
复杂度应该不超过
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define endl '\n'
constexpr i64 Mod = 1000000007;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
void solve() {
i64 a, b;
cin >> a >> b;
vector<vector<i64>> dp(20, vector<i64> (1 << 4, 0));
vector<vector<i64>> ndp(20, vector<i64> (1 << 4, 0));
for (int i = 0; i < 10; i++) {
dp[1][i] = 1;
}
for (int i = 0; i < 10; i++) {
ndp[1][i] = 1;
}
for (int i = 2; i < 20; i++) {
for (int j = 0; j < (1 << 4); j++) {
for (int k = 0; k < 10; k++) {
dp[i][j ^ k] += dp[i - 1][j];
}
}
}
for (int i = 2; i < 20; i++) {
for (int j = 0; j < (1 << 4); j++) {
for (int k = 1; k < 10; k++) {
ndp[i][j ^ k] += dp[i - 1][j];
}
}
}
i64 ans = 0;
vector<int> sep;
auto dfs = [&](auto &&self, int u, int cur) -> void {
if (u >= sep.size()) {
return;
}
if (u == sep.size() - 1) {
for (int i = 0; i <= sep[u]; i++) {
ans += (cur ^ i) == 0;
}
return;
}
if (!u) {
for (int i = 1; i < sep[u]; i++) {
ans += dp[sep.size() - u - 1][cur ^ i];
}
self(self, u + 1, cur ^ sep[u]);
} else {
for (int i = 0; i < sep[u]; i++) {
ans += dp[sep.size() - u - 1][cur ^ i];
}
self(self, u + 1, cur ^ sep[u]);
}
};
if (a) {
a--;
for (int i = 1; i < to_string(a).size(); i++) {
ans += ndp[i][0];
}
while (a) {
sep.emplace_back(a % 10);
a /= 10;
}
reverse(sep.begin(), sep.end());
dfs(dfs, 0, 0);
ans *= -1;
sep.clear();
}
for (int i = 1; i < to_string(b).size(); i++) {
ans += ndp[i][0];
}
while (b) {
sep.emplace_back(b % 10);
b /= 10;
}
reverse(sep.begin(), sep.end());
dfs(dfs, 0, 0);
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
K 慢慢来
暴力枚举选择
天的次数即可,复杂度
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define endl '\n'
constexpr i64 Mod = 1000000007;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
void solve() {
int a, b;
cin >> a >> b;
int n;
cin >> n;
for (int i = 0; i * (a + 1) <= n; i++) {
int x = n - (i * (a + 1));
if (x % (b + 1) == 0) {
cout << "YES" << endl;
return;
}
}
cout << "NO" << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
L 来日方长
按照题意输出图形,复杂度
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define endl '\n'
constexpr i64 Mod = 1000000007;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
void solve() {
int n;
cin >> n;
int m = (n * 2 + 1) * 2;
cout << "be happy" << endl;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n - i + 1; j++) {
cout << ' ';
}
for (int j = 1; j <= 2 * i - 1; j++) {
cout << "*";
}
for (int j = m - 2 * (n + i); j >= 1; j--) {
cout << ' ';
}
for (int j = 1; j <= 2 * i - 1; j++) {
cout << "*";
}
cout << endl;
}
for (int i = 1; i <= 2 * n + 1; i++) {
for (int j = 1; j <= i - 1; j++) {
cout << ' ';
}
for (int j = m - 2 * (i - 1); j >= 1; j--) {
cout << '*';
}
cout << endl;
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}



京公网安备 11010502036488号