0707A/A+
已结束
IOI
开始于: 2026-7-7 14:30
3
小时
主持人:
44
#include <bits/stdc++.h>
using namespace std;
const int N = 5e6 + 5;
#define int long long
int n, k, a[N];
int c[N], cj[N], cjj[N];
int Get(int i, int j, int p) {
//当前怪物在i点,能接受最远的攻击为j,
return (p - i * i) * (c[i] - c[j]) + 2 * i * (cj[i] - cj[j]) - (cjj[i] - cjj[j]);
}
int check(int p) {
int x = sqrt(p), res = k;
for (int i = n; i >= 1; i--) {
int B = Get(i, i + x, p);
int tmp = (max(-p, a[i] - B) + p) / p;
res -= tmp;
if (res < 0)
return 0;
c[i - 1] = c[i] + tmp;
cj[i - 1] = cj[i] + tmp * i;
cjj[i - 1] = cjj[i] + tmp * i * i;
}
return 1;
}
signed main() {
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
int l = 1, r = 1e11, res = -1;
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid)) {
r = mid - 1;
res = mid;
} else
l = mid + 1;
}
cout << res << endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 4e5 + 5;
#define int long long
int n, d[N];
int dis[N][2], son[N][2], f[N], g[N];
//dis[x][0]从x出发到子树的最远距离 dis[x][1]从x出发到子树的次远距离
//son[x][0]从x出发到子树的最远距离经过的儿子,son[x][1]从x出发到子树的次远距离经过的儿子
struct node {
int v, w;
};
vector<node>e[N];
void dfs1(int x, int fa) {
for (int i = 0; i < e[x].size(); i++) {
int v = e[x][i].v;
int w = e[x][i].w;
if (v == fa)
continue;
dfs1(v, x);
if (dis[v][0] + w >= dis[x][0]) {
dis[x][1] = dis[x][0];
son[x][1] = son[x][0];
dis[x][0] = dis[v][0] + w;
son[x][0] = v;
} else if (dis[v][0] + w > dis[x][1]) {
dis[x][1] = dis[v][0] + w;
son[x][1] = v;
}
}
}
void dfs2(int x, int fa, int w) {
if (son[x][0] != x + n)
f[x] = dis[x][0];
else
f[x] = dis[x][1];
if (son[fa][0] != x) {
g[x] = max(g[fa] + w, dis[fa][0] + w);
} else
g[x] = max(g[fa] + w, dis[fa][1] + w);
f[x] = max(f[x], g[x]);
for (int i = 0; i < e[x].size(); i++) {
int v = e[x][i].v;
int w = e[x][i].w;
if (v == fa)
continue;
dfs2(v, x, w);
}
}
signed main() {
cin >> n;
for (int i = 1; i < n; i++) {
int x, y, z;
cin >> x >> y >> z;
e[x].push_back({y, z});
e[y].push_back({x, z});
}
for (int i = 1; i <= n; i++) {
cin >> d[i];
}
for (int i = 1; i <= n; i++) {
e[i].push_back({i + n, d[i]});
e[i + n].push_back({i, d[i]});
}
dfs1(1, 0);
dfs2(1, 0, 0);
for (int i = 1; i <= n; i++) {
cout << f[i] << '\n';
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n, m, x, a[N];
int tree[N << 2], tag[N << 2];
void pushup(int rt) {
tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}
void pushdown(int l, int r, int rt) {
if (tag[rt]!=-1) {
tag[rt << 1] = tag[rt];
tag[rt << 1 | 1] = tag[rt];
int mid = (l + r) >> 1;
tree[rt << 1] = tag[rt] * (mid - l + 1);
tree[rt << 1 | 1] = tag[rt] * (r - mid);
tag[rt] = -1;
}
}
void build(int l, int r, int rt) {
tag[rt] = -1;
if (l == r) {
tree[rt] = (a[l] > x);
return;
}
int mid = (l + r) >> 1;
build(l, mid, rt << 1);
build(mid + 1, r, rt << 1 | 1);
pushup(rt);
}
void update(int l, int r, int rt, int L, int R, int c) {
if (L <= l && r <= R) {
tree[rt] = c * (r - l + 1);
tag[rt] = c;
return;
}
int mid = (l + r) >> 1;
pushdown(l, r, rt);
if (L <= mid)
update(l, mid, rt << 1, L, R, c);
if (R > mid)
update(mid + 1, r, rt << 1 | 1, L, R, c);
pushup(rt);
}
int query(int l, int r, int rt, int L, int R) {
if (L <= l && r <= R) {
return tree[rt];
}
pushdown(l, r, rt);
int mid = (l + r) >> 1;
int sum = 0;
if (L <= mid)
sum += query(l, mid, rt << 1, L, R);
if (R > mid)
sum += query(mid + 1, r, rt << 1 | 1, L, R);
return sum;
}
int main() {
cin >> n >> m >> x;
int res = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (a[i] == x) {
res = i;
}
}
build(1, n, 1);
for (int i = 1; i <= m; i++) {
int op, l, r;
cin >> op >> l >> r;
if (op == 1) {
int tmp = query(1, n, 1, l, r); //tmp代表l~r大于x的数的数量
//r-l+1-tmp
//l~r 1~5 1 1 1 1 1
if(tmp!=r-l+1)
update(1, n, 1, l, r - tmp, 0);
if(tmp!=0)
update(1, n, 1, r - tmp + 1, r, 1);
if (res >= l && res <= r) {
res = r - tmp;
}
} else {
int tmp = query(1, n, 1, l, r);
if(tmp!=0)
update(1, n, 1, l, l + tmp - 1, 1);
if(tmp!=r-l+1)
update(1, n, 1, l + tmp, r, 0);
if (res >= l && res <= r) {
res = l + tmp;
}
}
}
cout << res << endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5e5 + 5;
int n, B, m, a[N];
int tree[N << 2], tag[N << 2];
int sum[N];
void pushup(int rt) {
tree[rt] = max(tree[rt << 1], tree[rt << 1 | 1]);
}
void pushdown(int rt) {
if (tag[rt]) {
tag[rt << 1] += tag[rt];
tag[rt << 1 | 1] += tag[rt];
tree[rt << 1] += tag[rt];
tree[rt << 1 | 1] += tag[rt];
tag[rt] = 0;
}
}
void build(int l, int r, int rt) {
if (l == r) {
tree[rt] = sum[l];
return;
}
int mid = (l + r) >> 1;
build(l, mid, rt << 1);
build(mid + 1, r, rt << 1 | 1);
pushup(rt);
}
void update(int l, int r, int rt, int L, int R, int c) {
if (L <= l && r <= R) {
tag[rt] += c;
tree[rt] += c;
return;
}
pushdown(rt);
int mid = (l + r) >> 1;
if (L <= mid)
update(l, mid, rt << 1, L, R, c);
if (R > mid)
update(mid + 1, r, rt << 1 | 1, L, R, c);
pushup(rt);
}
double query(int l, int r, int rt, int c) {
if (l == r) {
return 1.0 * tree[rt] / l + B;
}
pushdown( rt);
int mid = (l + r) >> 1;
if (tree[rt << 1] >= c)
return query(l, mid, rt << 1, c);
else
return query(mid + 1, r, rt << 1 | 1, c);
}
signed main() {
cin >> n >> B >> m;
int tot = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
sum[i] = sum[i - 1] + a[i] - B;
tot += a[i];
}
build(1, n, 1);
while (m--) {
int c, x;
cin >> c >> x;
tot -= a[c];
update(1, n, 1, c, n, x - a[c]);
tot += x;
a[c] = x;
if (tree[1] < 0)
cout << fixed << setprecision(15) << 1.0 * tot / n << endl;
else
cout << fixed << setprecision(15) << query(1, n, 1, 0) << endl;
}
return 0;
}
- 状态
- 已结束
- 规则
- IOI
- 题目
- 4
- 开始于
- 2026-7-7 14:30
- 结束于
- 2026-7-7 17:30
- 持续时间
- 3 小时
- 主持人
- 参赛人数
- 44