codeforces educational round110 e

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值