专栏文章
YBOI-3题解
题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mio2ouua
- 此快照首次捕获于
- 2025/12/02 12:23 3 个月前
- 此快照最后确认于
- 2025/12/02 12:23 3 个月前
J3-T1
设 且 ,那么填 个 ,剩下填 时是 最少的方案,此后可以 个一组的增加 的数量,来替换掉 个 。
可以增加的次数为 ,答案在其基础上 即可。
注意若 则 的数量不足以换足够的 ,此时答案为 。
难度:中位橙
J3-T2
注意到 ,那么 ,于是分类讨论:
-
,此时序列全 ,,特判即可。
-
,此时
- ,无解。
- ,仅存在 个 。
- ,存在 个 。
-
若子段里有 个 ,目标为 个,那么需修改 次。
对于子段内 的数量,前缀和即可。
所有修改方法取 即可。
仅给出核心代码:
CPPfor(int i=1;i<=n;i++)
cin>>a[i],s[i]=s[i-1]+a[i];
while(q--){
cin>>l>>r>>k;
if(s[r]-s[l-1]==r-l+1&&r-l+1==k+1)
cout<<abs(k+1-(s[r]-s[l-1]))<<'\n';
else if(r-l+1<=k)
cout<<-1<<'\n';
else
cout<<abs(k-(s[r]-s[l-1]))<<'\n';
}
难度:高位橙
J3-T3
其实无向无环联通图就是树,题目背景里有提及推广做法,发现与中位数所求相似,于是推广做法至本题。
具体来说,问题转化为求令所有子树大小最大值最小的点。
不妨设 为以 为根时的最大子树,设 为以 为根的子树的大小。
先钦定 为根。
记 为 的儿子,显然有转移:
考虑父亲节点的贡献:
此时取到最小的 的 就是所求的 ,有了 之后计算 便是容易的。
给出核心代码:
CPPvoid dfs(int u,int fa){
sz[u]=1;
for(int v:g[u]){
if(v==fa) continue;
dfs(v,u);
f[u]=max(f[u],sz[v]);
sz[u]+=sz[v];
}
f[u]=max(f[u],n-sz[u]);
}
难度:中位黄
S3-T1
记 。
不妨设 为考虑到位置 的最大长度和。
考虑讲 按 排序,若相同则按 排序。
设目前考虑到了 ,则有:
此时是 的。
考虑使用树状数组维护 的前缀最大值,答案为 。
这就是出题人的 做法。
其实注意到转移式中的 是静态的,直接线性求前缀最大值即可,可以做到 ,瓶颈在于排序。
进一步的思考,值域不大,考虑按 计数排序,再对相同的 按 排序,在随机数据下近似 。
给出核心代码:
CPP//计数排序
for(int i=1;i<=n;i++) g[a[i].x].push_back(a[i].y);
for(int i=0;i<M;i++) sort(g[i].begin(),g[i].end());
for(int i=0;i<M;i++)
for(int j:g[i])
a[++p].x=i,a[p].y=j;
//dp
for(int i=1;i<=n;i++){
while(now<a[i].x) maxn=max(maxn,f[now++]);
int res=maxn+a[i].y-a[i].x+1;
f[a[i].y]=max(res,f[a[i].y]);
ans=max(ans,res);
}
难度:中位绿
S3-T2
设 为 单位时间后在 路口的方案数,有转移:
特别的,。
注意到转移式可以转为矩阵形式:
0&1&0&0&0&0&0&1\\
1&0&1&0&0&0&0&0\\
0&1&0&1&0&0&0&0\\
0&0&1&0&1&0&0&0\\
0&0&0&0&0&0&0&0\\
0&0&0&0&1&0&1&0\\
0&0&0&0&0&1&0&1\\
1&0&0&0&0&0&1&0\\
\end{matrix}\right]$$
然后矩阵乘法即可,时间复杂度为 $O(w^3\log n)$,$w=8$。
从另一个角度思考,设 $f_i$ 为第 $i$ 秒到第 $5$ 路口的方案数。
显然走偶数单位时间才能到达,由上面的转移式可以推出(中间可以自己推,懒得写了):
$$f_i=4f_{i-2}-2f_{i-4}$$
按此构造矩阵,则 $w=2$。
难度:中位蓝
#### 后两题做法过于抽象,想学习者找我问。相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...