AtCoder Beginner Contest 202

考试情况

前三题顺风顺水,除了没开long long挂了一发…
8分钟搞掉三题,状态非常好
第四题一眼看出来像是19年提高组T1格雷码,只是稍微加了一点处理
首先要求出总方案数,这个可以用组合数求解,由于满足题目要求的最大的组合数也不会爆long long,但如果阶乘加逆元去求解组合数,就一定会爆掉,所以选择用递推求出这个组合数
然后用二分思想搞一下,就搞定了,中途在左右端点上迷了一下,但后来还是成功绕回来了,45分钟搞掉了D题
然后就是每周的自闭日常…

题解

E

E题的关键在于一个巧妙地转化
比赛过程中思考到的最深处就是把每个深度的点存在vector里,然后再去找有哪些符合第一个约束条件,但当所有点都位于同一层,遍历就会复杂度爆炸
这时就需要用上这个转化,记录每个点开始被扫描的时间in,以及它的所有子树被扫描完的时间out
一个节点 y y y是另一个节点 x x x需要满足的约束条件为
i n y ≤ i n x < o u t y in_y\leq in_x < out_y inyinx<outy
而对于同一深度的点,它的 i n in in是单调递增的,故可以直接用lower_bound二分找出符合上述两个不等式的两端点,相减即为答案
值得一提的是,vector的lower_bound 用法与数组不同,具体写法见下文代码

#include<bits/stdc++.h>
using namespace std;
int tot=0;
const int N=2e5+10;
int in[N],out[N],dep[N];
vector<int> Dep[N];
vector<int> chi[N];
void dfs(int u)
{
	in[u]=tot++;
	Dep[dep[u]].push_back(in[u]);
	for(int i=0;i<chi[u].size();i++)
	{
		dep[chi[u][i]]=dep[u]+1;
		dfs(chi[u][i]);
	}
	out[u]=tot++;
}
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<n;i++)
	{
		int p;
		cin>>p;
		chi[p].push_back(i+1);
	}
	dfs(1);
	int q;
	cin>>q;
	for(int i=1;i<=q;i++)
	{
		int u,d;
		cin>>u>>d;
		cout<<(lower_bound(Dep[d].begin(),Dep[d].end(),out[u])-Dep[d].begin())-(lower_bound(Dep[d].begin(),Dep[d].end(),in[u])-Dep[d].begin())<<endl;
	}
	return 0;
}

总结

1.前几题A的越来越熟练,但还总是出现不开long long的错误,数据范围的观察并计算还需提升
2.学会了vector的lower_bound 用法
3.观察数据范围还是有用的,考试过程中想到了用二分去优化,但只是有这个念头,却根本不会实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值