codeforces educational round110 e
给一颗初始只有根节点0的树,规定一个节点有数量 a i a_i ai,单位价格为 c i c_i ci的矿物。q个操作,一是往某一个节点下增加一个节点,保证增加的节点的单位价格比这个节点高;二是选择某个节点,从根节点到当前节点路径上购买 w w w个货物,要求价格和最小,如果不够就能买多少买多少。
做这个题的时候少看了一个条件,没看到保证比父亲节点价格高,所以不会。后面发现别人写的代码都是树上倍增,才知道题读错了。不过反正树上倍增也不熟……
const int N = 3e5 + 10;
int fa[N][21], a[N], c[N];
int main()
{
int T = 1;
//T = read();
while (T --)
{
int q;
q = read(); a[0] = read(); c[0] = read();
for (int i = 0; i <= 20; i ++)
fa[0][i] = -1;
for (int i = 1; i <= q; i ++)
{
int jud = read();
if (jud == 1)
{
fa[i][0] = read();
a[i] = read();
c[i] = read();
for (int k = 1; k <= 20; k ++)
{
if (fa[i][k - 1] == -1)
fa[i][k] = -1;
else
fa[i][k] = fa[fa[i][k - 1]][k - 1];
}
}
else
{
int v, w;
v = read(); w = read();
int temp = w;
long long ans = 0;
while (temp > 0 && a[v] > 0)
{
int d = v;
for (int i = 20; i >= 0; i --)
{
while (fa[d][i] != -1 && a[fa[d][i]] > 0)
d = fa[d][i];
}
int now = min(temp, a[d]);
temp -= now; a[d] -= now; ans += (long long) now * c[d];
}
printf ("%d %lld\n", w - temp, ans);
fflush(stdout);
}
}
}
return 0;
}