看板娘加载较慢请耐心等待qwq~~~

ECNU XCPC 2021 OCTOBER TRAINING #1

ECNU XCPC 2021 OCTOBER TRAINING #1

诶嘿没想到吧这个博客更新le

A 鸡兔同笼

question

在一个笼子里关着一个头两只脚的鸡,一个头三只脚的东西,一个头四只脚的兔子,给头和脚,求兔子最多最少有几只

sov

直接贪心,兔子最多的时候全是鸡,最少的时候全是猫。解一下方程组即可

ans1 = y - 3 * x;
ans1 = max(0, ans1);
ans2 = y / 2 - x;
cout << ans1 << " " << ans2 << endl;

B 小喵的晚会

question

给一个数列,尽可能的从中减掉最多的值,且操作后的数各不相同

sov

把数组从小到大排序,对每一个数,从小到大枚举它可以剩余的最小的数

sort(a + 1, a + n, cmp);
for(register int i = 1; i < n; ++i)
{
	register int j = i;
	while(v[j]) ++j;
	a[n].num += a[i].num - j;
	a[i].num = j;
	v[a[i].num] = true;
}

std

从小到大排序,没个数分别拿到只剩1,2,3……

C魔树

question

给一棵树,接下来进行操作
D: 删除所有的叶节点
A k:在每一个叶节点下加k个叶节点

sov

记录每一个点在第几层,然后进行模拟操作

//d是记录每个节点距离最深的子节点多远
inline void dfs(int fa, int x)
{
	int mx = 0;
	for(register int i = head[x]; i; i = nxt[i])
	{
		if(ver[i] == fa)
			continue;
		dfs(x, ver[i]);
		mx = max(d[ver[i]], mx);
	}
	d[x] = mx + 1;
}
int main()
{
    //处理每个节点,d是该节点在第几层叶子,cnt是该层有几个叶子
    //pt指向当前最深的一层
    for(register int i = 1; i <= n; ++i)
	{
		d[i] = pt - d[i] + 1;
		++cnt[d[i]];
	}
    //A操作只需要下一层有当前层的叶子数 * k
	for(register int i = 1; i <= m; ++i)
	{
		if(c == 'D')
			--pt;
		else
		{
			cin >> k;
			cnt[pt + 1] = 1ll * cnt[pt] * k % MOD;
			++pt;
		}
	}
}

more

可以使用双端队列维护操作,将重叠的A和D删去,减少操作数(复杂度上没啥变化反正是O(1)操作)

posted @ 2021-10-07 00:18  椎名·六花  阅读(35)  评论(1编辑  收藏  举报