Gravatar
Fall
积分:7
提交:3 / 8
下面这组数据大佬们都输出什么啊:
5 3
2 2 5 9 5
10 7 7 1 3
1 2
2 3
2 4
4 5
手算0.375,输出二分左边界就是0.37,右边界0.38。
数据是不是应该注意这个精度问题啊,好像有些代码这个数据会输出错误答案。

Gravatar
xjr
积分:1
提交:1 / 8
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cmath>
using namespace std;
int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
#define maxn 200010
#define maxm 400010
#define ool (1ll << 60)
#define LL long long
int n, K, A[maxn], B[maxn], m, head[maxn], nxt[maxm], to[maxm];
void AddEdge(int a, int b) {
to[++m] = b; nxt[m] = head[a]; head[a] = m;
swap(a, b);
to[++m] = b; nxt[m] = head[a]; head[a] = m;
return ;
}
int fa[maxn], son[maxn], mxd[maxn], dep[maxn], pos[maxn], clo;
void build(int u) {
mxd[u] = dep[u];
for(int e = head[u]; e; e = nxt[e]) if(to[e] != fa[u]) {
fa[to[e]] = u;
dep[to[e]] = dep[u] + 1;
build(to[e]);
mxd[u] = max(mxd[u], mxd[to[e]]);
if(!son[u] || mxd[to[e]] > mxd[son[u]]) son[u] = to[e];
}
return ;
}
void gett(int u) {
pos[u] = ++clo;
if(son[u]) gett(son[u]);
for(int e = head[u]; e; e = nxt[e]) if(to[e] != fa[u] && to[e] != son[u]) gett(to[e]);
return ;
}
LL ans, mns[maxn];
void solve(int u, int x) {
if(son[u]) solve(son[u], x);
mns[pos[u]] = A[u] - (LL)x * B[u];
for(int i = 1; i <= mxd[u] - dep[u]; i++) mns[pos[u]+i] += A[u] - (LL)x * B[u];
for(int e = head[u]; e; e = nxt[e]) if(to[e] != fa[u] && to[e] != son[u]) {
solve(to[e], x);
for(int i = 0; i <= min(mxd[to[e]] - dep[to[e]], K); i++)
if(K - i - 1 <= mxd[u] - dep[u])
ans = min(ans, mns[pos[to[e]]+i] + mns[pos[u]+K-i-1]);
for(int i = 0; i <= mxd[to[e]] - dep[to[e]]; i++)
mns[pos[u]+i+1] = min(mns[pos[u]+i+1], mns[pos[to[e]]+i] + A[u] - (LL)x * B[u]);
}
if(K <= mxd[u] - dep[u]) ans = min(ans, mns[pos[u]+K]);
/*printf("leader: %d (now checking %d) %lld\n", u, x, A[u] - (LL)x * B[u]);
for(int i = 0; i <= mxd[u] - dep[u]; i++)
printf("%lld%c", mns[pos[u]+i], i < mxd[u] - dep[u] ? ' ' : '\n'); // */
return ;
}
int main() {
freopen("cdcq_b.in", "r", stdin);
freopen("cdcq_b.out", "w", stdout);
n = read(); K = read();
for(int i = 1; i <= n; i++) A[i] = read() * 2000;
for(int i = 1; i <= n; i++) B[i] = read();
for(int i = 1; i < n; i++) {
int a = read(), b = read();
AddEdge(a, b);
}
if(K < 0) {
double s = (double)ool;
for(int i = 1; i <= n; i++) s = min(s, (double)A[i] / B[i]);
printf("%.2lf\n", s);
return 0;
}
K--;
build(1);
gett(1);
// for(int i = 1; i <= n; i++) printf("%d: [%d] %d %d\n", i, pos[i], dep[i], mxd[i]);
int l = 0, r = 400000000;
while(l < r) {
int mid = l + r >> 1;
ans = ool;
for(int i = 1; i <= n; i++) mns[i] = ool;
solve(1, mid);
if(ans > 0) l = mid + 1; else r = mid;
}
printf("%.2lf\n", l / 2000.0);
return 0;
}

这份代码为何总是编译失败?!求助!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Gravatar
fjzzq2002
积分:57
提交:10 / 23
技不如人,甘拜下风。
在一些奥妙重重的地方写挂了啊= =
这题可以一个log的

Gravatar
FoolMike
积分:5200
提交:1165 / 2240
没有特判,丢了30……真TMD智障
分数规划是什么鬼,我好想只知道下凸包上三分求斜率最小的点……

Gravatar
FoolMike
积分:5200
提交:1165 / 2240
m=-1表示无限制……

Gravatar
__stdcall
积分:420
提交:75 / 218
技不如人,甘拜下风。
好写不好调的点分治,一上午搭进去了。

Gravatar
confoo
积分:905
提交:222 / 728
技不如人,甘拜下风。