Idea: BledDest
t = int(input())
for i in range(t):
n, m, k = map(int, input().split())
d = n // k
a1 = min(m, d)
a2 = (m - a1 + k - 2) // (k - 1)
print(a1 - a2)
1359B - Новая Театральная площадь
Idea: BledDest
t = int(input())
for _ in range(t):
n, m, x, y = map(int, input().split())
ans = 0
y = min(y, 2 * x)
for __ in range(n):
s = input()
i = 0
while i < m:
if s[i] == '*':
i += 1
continue
j = i
while j + 1 < m and s[j + 1] == '.':
j += 1
l = j - i + 1
ans += l % 2 * x + l // 2 * y
i = j + 1
print(ans)
Idea: adedalic
So there are two kinds of stops to consider: $$$k$$$ hot and $$$k$$$ cold cup and $$$(k + 1)$$$ hot and $$$k$$$ cold cups.
The first case is trivial: the temperature is always $$$\frac{h + c}{2}$$$. In the second case the temperature is always strictly greater than $$$\frac{h + c}{2}$$$. Thus, if $$$t \le \frac{h + c}{2}$$$, then the answer is $$$2$$$.
Let's show that otherwise the answer is always achieved through the second case.
The temperature after $$$(k + 1)$$$ hot cups and $$$k$$$ cold cups is $$$t_k = \frac{(k + 1) \cdot h + k \cdot c}{2k + 1}$$$. The claim is that $$$t_0 > t_1 > \dots$$$. Let's prove that by induction.
$$$t_0 = h, t_1 = \frac{2 \cdot h + c}{3}$$$. $$$c < h$$$, thus $$$t_0 > t_1$$$.
Now compare $$$t_k$$$ and $$$t_{k+1}$$$.
We can also show that this series converges to $$$\frac{h + c}{2}$$$:
I'm sorry that I'm not proficient with any calculus but my intuition says that it's enough to show that $$$\forall k~t_k > \frac{h + c}{2}$$$ and $$$\forall \varepsilon \exists k~t_k < \frac{h + c}{2}$$$ with $$$k \ge 0$$$.
So the first part is:
And the second part is:
So that claim makes us see that for any $$$t$$$ greater than $$$\frac{h + c}{2}$$$ the answer is always achieved from the second case.
That allows us to find such $$$k$$$, that the value of $$$t_k$$$ is exactly $$$t$$$. However, such $$$k$$$ might not be integer. $$$\frac{(k + 1) \cdot h + c}{2k + 1} = t \leftrightarrow$$$ $$$\frac{k \cdot (h + c) + h}{2k + 1} = t \leftrightarrow$$$ $$$k \cdot (h + c) + h = 2kt + t \leftrightarrow$$$ $$$k \cdot (h + c - 2t) = t - h \leftrightarrow$$$ $$$k = \frac{t - h}{h + c - 2t}$$$.
The only thing left is to compare which side is better to round $$$k$$$ to. It seems some implementations with float numbers might fail due to precision errors. However, it's possible to do these calculations completely in integers.
Let's actually rewrite that so that the denominator is always positive $$$k = \frac{h - t}{2t - h - c}$$$. Now we can round this value down and compare $$$k$$$ and $$$k + 1$$$.
So the optimal value is $$$k$$$ if $$$|\frac{k \cdot (h + c) + h}{2k + 1} - t| \le |\frac{(k + 1) \cdot (h + c) + h}{2k + 3}| - t$$$. So $$$|(k \cdot (h + c) + h) - t \cdot (2k + 1)| \cdot (2k + 3) \le |((k + 1) \cdot (h + c) + h) - t \cdot (2k + 3)| \cdot (2k + 1)$$$. Otherwise, the answer is $$$k + 1$$$.
You can also find the optimal $$$k$$$ with binary search but the formulas are exactly the same and you have to rely on monotonosity as well. Also, these formulas can get you the better understanding for the upper bound of the answer.
Overall complexity: $$$O(1)$$$ or $$$O(\log h)$$$ per testcase.
#include <bits/stdc++.h>
#define forn(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
int main() {
int tc;
scanf("%d", &tc);
forn(_, tc){
int h, c, t;
scanf("%d%d%d", &h, &c, &t);
if (h + c - 2 * t >= 0)
puts("2");
else{
int a = h - t;
int b = 2 * t - c - h;
int k = 2 * (a / b) + 1;
long long val1 = abs(k / 2 * 1ll * c + (k + 1) / 2 * 1ll * h - t * 1ll * k);
long long val2 = abs((k + 2) / 2 * 1ll * c + (k + 3) / 2 * 1ll * h - t * 1ll * (k + 2));
printf("%d\n", val1 * (k + 2) <= val2 * k ? k : k + 2);
}
}
return 0;
}
1359D - Очередная очередная задача
Idea: BledDest
#include <bits/stdc++.h>
#define forn(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
const int INF = 1e9;
int main() {
int n;
scanf("%d", &n);
vector<int> a(n);
forn(i, n) scanf("%d", &a[i]);
long long ans = 0;
forn(mx, 31){
long long cur = 0;
long long best = 0;
forn(i, n){
int val = (a[i] > mx ? -INF : a[i]);
cur += val;
best = min(best, cur);
ans = max(ans, (cur - best) - mx);
}
}
printf("%lld\n", ans);
return 0;
}
1359E - Модульная стабильность
Idea: BledDest
#include<bits/stdc++.h>
using namespace std;
const int N = 500043;
const int MOD = 998244353;
int fact[N];
int add(int x, int y)
{
x += y;
while(x >= MOD) x -= MOD;
while(x < 0) x += MOD;
return x;
}
int mul(int x, int y)
{
return (x * 1ll * y) % MOD;
}
int binpow(int x, int y)
{
int z = 1;
while(y > 0)
{
if(y % 2 == 1)
z = mul(z, x);
x = mul(x, x);
y /= 2;
}
return z;
}
int inv(int x)
{
return binpow(x, MOD - 2);
}
int divide(int x, int y)
{
return mul(x, inv(y));
}
void precalc()
{
fact[0] = 1;
for(int i = 1; i < N; i++)
fact[i] = mul(i, fact[i - 1]);
}
int C(int n, int k)
{
if(k > n) return 0;
return divide(fact[n], mul(fact[n - k], fact[k]));
}
int main()
{
int n, k;
cin >> n >> k;
int ans = 0;
precalc();
for(int i = 1; i <= n; i++)
{
int d = n / i;
ans = add(ans, C(d - 1, k - 1));
}
cout << ans << endl;
}
1359F - Шоу взрывов на радиоуправлении
Idea: BledDest
#include <bits/stdc++.h>
#define forn(i, n) for (int i = 0; i < int(n); i++)
#define x first
#define y second
using namespace std;
const double INF = 1e13;
struct line{
int A, B, C;
line(){}
line(int x1, int y1, int x2, int y2){
A = y1 - y2;
B = x2 - x1;
C = -A * x1 - B * y1;
// A is guaranteed to be non-zero
if (A < 0) A = -A, B = -B, C = -C;
int g = __gcd(A, __gcd(abs(B), abs(C)));
A /= g, B /= g, C /= g;
}
};
bool operator ==(const line &a, const line &b){
return a.A == b.A && a.B == b.B && a.C == b.C;
}
double x;
struct comp{
bool operator ()(const pair<line, int> &a, const pair<line, int> &b) const {
double val1 = (-a.x.A * x - a.x.C) / a.x.B;
double val2 = (-b.x.A * x - b.x.C) / b.x.B;
if (val1 != val2)
return val1 < val2;
return a.y < b.y;
}
};
struct car{
int x, y, dx, dy, s;
line l;
double vx, vy;
};
int n;
vector<car> a(n);
long long det(int a, int b, int c, int d){
return a * 1ll * d - b * 1ll * c;
}
bool inter(const line &a, const line &b, long long &D, long long &Dx, long long &Dy){
D = det(a.A, a.B, b.A, b.B);
if (D == 0) return false;
Dx = -det(a.C, a.B, b.C, b.B);
Dy = -det(a.A, a.C, b.A, b.C);
return true;
}
int sg(int x){
return x < 0 ? -1 : 1;
}
int sg(long long a, long long b, int c){
// sign of a/b-c
if (b < 0) a = -a, b = -b;
return a - c * b < 0 ? -1 : (a - c * b > 0);
}
bool inter(int i, int j, double &len){
if (i == -1 || j == -1)
return false;
long long D, Dx, Dy;
if (!inter(a[i].l, a[j].l, D, Dx, Dy))
return false;
if (sg(Dx, D, a[i].x) != 0 && sg(a[i].dx) != sg(Dx, D, a[i].x))
return false;
if (sg(Dx, D, a[j].x) != 0 && sg(a[j].dx) != sg(Dx, D, a[j].x))
return false;
double x = Dx / double(D);
double y = Dy / double(D);
double di = sqrt((a[i].x - x) * (a[i].x - x) + (a[i].y - y) * (a[i].y - y));
double dj = sqrt((a[j].x - x) * (a[j].x - x) + (a[j].y - y) * (a[j].y - y));
return len >= max(di / a[i].s, dj / a[j].s);
}
vector<char> del;
set<pair<line, int>, comp> q;
void get_neighbours(int i, int &l, int &r){
l = r = -1;
auto it = q.lower_bound({a[i].l, -1});
while (it != q.end() && del[it->y])
it = q.erase(it);
if (it != q.end())
r = it->y;
while (!q.empty() && it != q.begin()){
--it;
if (del[it->y])
it = q.erase(it);
else{
l = it->y;
break;
}
}
}
bool check(double t){
vector<pair<double, pair<int, int>>> cur;
del.assign(n, 0);
forn(i, n){
double x1 = a[i].x;
double x2 = a[i].x + a[i].vx * t;
if (x1 > x2) swap(x1, x2);
cur.push_back({x1, {i, 0}});
cur.push_back({x2, {i, 1}});
}
q.clear();
sort(cur.begin(), cur.end());
for (auto &qr : cur){
x = qr.x;
int i = qr.y.x;
int l, r;
if (qr.y.y == 0){
get_neighbours(i, l, r);
if (r != -1 && a[i].l == a[r].l)
return true;
if (inter(i, l, t))
return true;
if (inter(i, r, t))
return true;
q.insert({a[i].l, i});
}
else{
del[i] = true;
get_neighbours(i, l, r);
if (inter(l, r, t))
return true;
}
}
return false;
}
int main() {
scanf("%d", &n);
a.resize(n);
forn(i, n){
scanf("%d%d%d%d%d", &a[i].x, &a[i].y, &a[i].dx, &a[i].dy, &a[i].s);
a[i].l = line(a[i].x, a[i].y, a[i].x + a[i].dx, a[i].y + a[i].dy);
double d = sqrt(a[i].dx * a[i].dx + a[i].dy * a[i].dy);
a[i].vx = a[i].dx / d * a[i].s;
a[i].vy = a[i].dy / d * a[i].s;
}
double l = 0, r = INF;
bool ok = false;
forn(_, 100){
double m = (l + r) / 2;
if (check(m)){
ok = true;
r = m;
}
else{
l = m;
}
}
if (!ok)
puts("No show :(");
else
printf("%.15lf\n", l);
return 0;
}