atcoder 杂题 #05

news/2025/1/7 3:54:14/文章来源:https://www.cnblogs.com/dccy/p/18653914

atcoder 杂题 #05

  • abc340_g Leaf Color
  • abc340_f F - S = 1
  • abc361_g Go Territory
  • abc386_f Operate K

abc340_g

独立想出了这道题。

如果我们确定了子图的叶子,那么这个子图就确定了。又由于叶子的颜色要相同,所以每种颜色的贡献是互相独立的。

首先如果一种颜色有 \(x\) 个点,那么这种颜色的贡献并不是 \(2^x-1\),因为可能有一个合法的子图中,这种颜色的点不在叶子处,答案就会多算。

考虑枚举颜色,把这种颜色的点取出来,建出虚树。然后在虚树上 DP。接下来如果一个点的颜色为我们枚举的这个颜色,我们称这个点有颜色。

\(f_i\) 表示子树 \(i\) 内的合法子图数,这里的合法子图指包含 \(i\) 的合法子图或者是空集,如果是空集就要求 \(i\) 有颜色,这样才能不多算。那么就有

\[f_i=\prod_{j\in son_i} f_j \]

接下来,对于一个有颜色的点 \(i\),它可以作为合法子图的叶子,所以它的度数没有限制,答案直接加上 \(f_i\),再让 \(f_i\) 加一,表示可以为空集。

而对于一个没有颜色的点 \(i\),它不可以作为合法子图的叶子,即度数要大于一,于是答案在加 \(f_i\) 的基础上还要减去度数为一的子图和空集。即

\[ans+f_i-1-\Big(\sum_{j\in son_i}f_j-1\Big)\to ans \]

里面的 \(f_j-1\) 是因为要减去 \(j\) 子树为空集的情况。

时间复杂度的瓶颈在于建虚树,时间复杂度 \(O(n\log n)\)

AC 代码:

const int N=2e5+5;
vector<int> g[N],h[N];
int n,co[N];
vector<int> c[N];
int fa[N][18],dep[N],dfn[N],dfn1;
void dfs1(int x,int y){dep[x]=dep[y]+1,fa[x][0]=y,dfn[x]=++dfn1;fu(i,1,18)fa[x][i]=fa[fa[x][i-1]][i-1];for(int v:h[x])if(v!=y)dfs1(v,x);
}
int lca(int x,int y){if(dep[x]<dep[y])swap(x,y);for(int i=dep[x]-dep[y],j=0;i;i>>=1,++j)if(i&1)x=fa[x][j];if(x==y)return x;fd(i,17,0)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];return fa[x][0];
}
int d[N*2],tot,Co;
const int mod=998244353;
int f[N],ans;
void dfs2(int x,int y){f[x]=1;int sum=0;for(int v:g[x]){if(v==y)continue;dfs2(v,x);f[x]=(ll)f[x]*f[v]%mod;sum=(sum+f[v])%mod;sum=(sum-1)%mod;}if(co[x]==Co){ans=(ans+f[x])%mod;f[x]=(f[x]+1)%mod;}else{ans=(ans+f[x])%mod;ans=(ans+mod-sum-1)%mod;}
}
signed main(){cin>>n;fo(i,1,n)cin>>co[i],c[co[i]].push_back(i);fu(i,1,n){int u,v; cin>>u>>v;h[u].push_back(v),h[v].push_back(u);}dfs1(1,0);fo(i,1,n){if(!c[i].size())continue;d[tot=1]=1;for(auto j:c[i])d[++tot]=j;auto cmp=[](int x,int y)->bool{return dfn[x]<dfn[y];};sort(d+1,d+1+tot,cmp);for(int o=tot,i=2;i<=o;++i)d[++tot]=lca(d[i],d[i-1]);sort(d+1,d+1+tot,cmp);tot=unique(d+1,d+1+tot)-d-1;fo(i,1,tot)g[d[i]].clear();auto add=[](int x,int y)->void{g[x].push_back(y),g[y].push_back(x);return;};fo(i,2,tot)add(d[i],lca(d[i],d[i-1]));Co=i;dfs2(1,0);}cout<<ans<<'\n';return 0;
}

abc340_f

除夕夜的 abc 在 12 月才改出来。

假设 \((x,y),(a,b),(0,0)\) 组成了面积为 \(1\) 的三角形。用正方形减去三个三角形得

\[ay-\frac{xy}2-\frac{ab}2-\frac{(a-x)(y-b)}2=1 \]

\[\frac {ay-bx} 2=1 \]

\[ay-bx=2 \]

用 exgcd 解出 \(a,b\) 即可,根据 exgcd 的技巧,当 \(\gcd(y,x)\nmid2\) 时无解,记得最后要输出 \(a,-b\)

AC 代码:

#define int ll
int exgcd(int a,int b,int &x,int &y){if(b==0){x=1,y=0;return a;}int d=exgcd(b,a%b,y,x);y-=a/b*x;return d;
}
signed main(){int a,b;cin>>a>>b;int x,y;int d=exgcd(a,b,y,x);if(2%d!=0){cout<<"-1";return 0;}x*=2/d,y*=2/d;cout<<-x<<" "<<y<<"\n";return 0;
}

abc361_g

还记得是上个学期 2019pzr 还在的时候他讲的这道题,当时他好像还讲复杂了,没有听懂。

其实并不难写。

首先有一个 \(O(V^2)\) 的暴力,对于平面上的每一个点用并查集合并。

优化。考虑对于每一个 \(x\),给定的点把 \(y\) 分成了很多个段,发现一共是 \(O(n+V)\) 个段,用并查集合并这些段,用双指针扫一遍合并相邻 \(x\) 的每个段即可。

AC 代码:

const int N=1e6+5;
int n;
struct arr{int l,r,num;
};
int tot;
int fa[N],sz[N];
int getfa(int x){if(fa[x]==x)return x;return fa[x]=getfa(fa[x]);
}
vector<arr> a[N];
vector<int> pt[N];
signed main(){cin>>n;fo(i,1,n){int x,y;cin>>x>>y;pt[x].push_back(y);}fo(i,0,2e5){sort(pt[i].begin(),pt[i].end());if(pt[i].size()==0){a[i].push_back({0,(int)2e5,++tot});fa[tot]=tot,sz[tot]=2e5+1;}else if(pt[i][0]>0){a[i].push_back({0,pt[i][0]-1,++tot});fa[tot]=tot,sz[tot]=pt[i][0];	}fu(j,0,pt[i].size()){if(j+1==pt[i].size())continue;int u=pt[i][j],v=pt[i][j+1];if(u+1<v){a[i].push_back({u+1,v-1,++tot});fa[tot]=tot,sz[tot]=v-u-1;}}if(pt[i].size()>0){a[i].push_back({pt[i][pt[i].size()-1]+1,(int)2e5,++tot});fa[tot]=tot,sz[tot]=2e5-pt[i][pt[i].size()-1];}}fo(i,0,2e5){if(a[i].front().l==0)fa[a[i].front().num]=1;if(a[i].back().r==(int)2e5)fa[a[i].back().num]=1;}for(auto i:a[0])fa[i.num]=1;for(auto i:a[(int)2e5])fa[i.num]=1;fu(i,0,2e5){int k=0;for(auto j:a[i]){while(k<a[i+1].size()&&a[i+1][k].r<j.l)++k;if(k<a[i+1].size()&&a[i+1][k].l<=j.r){int u=getfa(j.num),v=getfa(a[i+1][k].num);if(u!=v)fa[u]=v;}while(k+1<a[i+1].size()&&a[i+1][k+1].l<=j.r){++k;int u=getfa(j.num),v=getfa(a[i+1][k].num);if(u!=v)fa[u]=v;}}}ll ans=0;fo(i,1,tot)if(getfa(i)!=getfa(1))ans+=sz[i];cout<<ans<<'\n';return 0;
}

abc386_f Operate K

题目大意:给定串 \(A,B\),可以做至多 \(K(K\le 20)\) 次以下操作之一:

  • \(A\) 中插入一个字符。
  • 删除 \(A\) 的一个字符。
  • 替换 \(A\) 的一个字符。

问最终能否将 \(A\) 变成 \(B\)

解题思路:首先暴力地想,设\(f_{i,j}\) 表示 \(A\) 的前 \(i\) 个考虑完后,匹配到 \(B\) 的第 \(j\) 个字符最少做多少次操作。

注意到只有 \(i-K\le j\le i+K\)\(j\) 是有用的,所以我们设新的 DP 状态 \(f_{i,j}(-K\le j\le K)\) 表示 \(A\) 的前 \(i\) 个考虑完后,匹配到 \(B\) 的第 \(i+j\) 个字符最少做多少次操作。

那么转移就是:

  • 插入 \(B\) 的下一个字符:\(f_{i,j}+1\to f_{i,j+1}\)
  • 删除 \(A\) 的下一个字符:\(f_{i,j}+1\to f_{i+1,j-1}\)
  • 替换 \(A\) 的下一个字符为 \(B\) 的下一个字符:\(f_{i,j}+1\to f_{i+1,j}\)
  • \(A_{i+1}=B_{i+j+1}\) 则直接匹配:\(f_{i,j}\to f_{i+1,j}\)

转移过程中要求操作数始终不大于 \(K\) 即可。

时间复杂度 \(O(nK)\),其中 \(n\) 为字符串的长度。

AC 代码:

int K;
const int N=5e5+5;
char a[N],b[N];
int n,m;
int f[N][45];
void get(int &x,int y){if(y<x)x=y;
}
signed main(){cin>>K;scanf("%s%s",a+1,b+1);n=strlen(a+1),m=strlen(b+1);memset(f,0x3f,sizeof f);f[0][0+K]=0;fo(i,0,n){fo(j,-K,K){if(f[i][j+K]>K||i+j<0||i+j>m)continue;if(j+K-1>=0)get(f[i+1][j+K-1],f[i][j+K]+1);get(f[i][j+K+1],f[i][j+K]+1);get(f[i+1][j+K],f[i][j+K]+1);if(a[i+1]==b[i+j+1])get(f[i+1][j+K],f[i][j+K]);}}if(m-n<=K&&m-n>=-K&&f[n][m-n+K]<=K)cout<<"Yes\n";else cout<<"No\n";return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/864561.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开启家具组装新方式:产品说明书智能指导

在快节奏的现代生活中,人们越来越追求便捷与高效。无论是新房装修还是家具换新,家具组装已成为许多家庭不可避免的一项任务。然而,面对复杂多变的家具图纸和冗长的产品说明书,许多人常常感到无从下手,甚至因操作不当而损坏零件。为了解决这一难题,一种全新的家具组装方式…

2024-2025-1 20241408陈烨南《计算机基础与程序设计》课程总结

每周作业链接汇总 第0周作业 自我介绍 https://www.cnblogs.com/chenyenai/p/18432520第1周作业 计算机基础与程序设计中的问题提问 https://www.cnblogs.com/chenyenai/p/18439433第2周作业 阅读《计算机科学概论》第一章和《C语言程序设计》第一章,并进行总结 https://www.c…

# 学期(如2024-2025-1) 学号(如:20241402) 《计算机基础与程序设计》第15周学习总结

学期(如2024-2025-1) 学号(如:20241402) 《计算机基础与程序设计》第15周学习总结 作业信息这个作业属于哪个课程 <班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>(如2024-2025-1计算机基础与程序设计第一周作业)这个…

SpringBoot进阶教程(八十四)spring-retry

在日常的一些场景中, 很多需要进行重试的操作.而spring-retry是spring提供的一个基于spring的重试框架,某些场景需要对一些异常情况下的方法进行重试就会用到spring-retry。spring-retry可以帮助我们以标准方式处理任何特定操作的重试。在spring-retry中,所有配置都是基于简单…

制造业知识中台:推动智能制造转型升级的智慧大脑

在当今全球制造业的激烈竞争中,智能制造已成为推动产业升级、提升竞争力的关键路径。制造业知识中台,作为连接数据、知识与业务的智慧中枢,正逐步展现出其在推动智能制造转型升级中的巨大潜力。它不仅能够帮助企业实现知识的有效整合与高效利用,还能通过智能化分析与应用,…

电子配件行业的未来之路:产品说明书数字化转型的力量

在科技飞速发展的今天,电子配件行业作为科技创新的前沿阵地,正经历着前所未有的变革。从智能手机、平板电脑到智能穿戴设备,各种新型电子配件层出不穷,极大地丰富了人们的生活。然而,随着产品种类的增多和功能的复杂化,如何确保消费者能够快速、准确地理解和使用这些产品…

基于四象限比例积分控制器的直流电机控制系统simulink建模与仿真

1.课题概述 基于四象限比例积分控制器的直流电机控制系统simulink建模与仿真。2.系统仿真结果 3.核心程序与模型 版本:MATLAB2022a4.系统原理简介直流电机由于其较好的调速性能和较高的控制精度,被广泛应用于各种工业控制场合。为了实现对直流电机转速和位置的精确控制,控制…

人工智能驱动的内部知识库:智能搜索、推荐与知识发现

随着人工智能技术的飞速发展,企业内部知识库的管理与应用方式正经历着前所未有的变革。智能搜索、个性化推荐与深度知识发现,这些曾经只存在于科幻小说中的场景,如今已借助AI技术,在企业的日常运营中成为现实。在这一变革浪潮中,HelpLook作为一款集成了先进AI算法的工具,…

视野修炼-技术周刊第116期 | NB Ping

① NB Ping - 多地址并发 Ping 工具 ② 动画图标 ③ RSS.Beauty - RSS 订阅源美化展示 ④ Console.trace:JavaScript调试的利器 ⑤ 关于跨端的前世今生 ⑥ LogoShip - 图标生成器欢迎来到第 116 期的【视野修炼 - 技术周刊】,下面是本期的精选内容简介 🔧开源工具&技术…

深度学习CUDA环境安装教程---动手学深度学习

首先说明我安装的是《动手学深度学习》中的环境 本人是小白,一次安装,可能有不对的地方,望包含。安装CUDA 因为我们是深度学习,很多时候要用到gpu进行训练,所以我们需要一种方式加快训练速度。 通俗地说,CUDA是一种协助“CPU任务分发+GPU并行处理”的编程模型/平台,用于…

基于龙格库塔算法的锅炉单相受热管建模与matlab数值仿真

1.程序功能描述 基于龙格库塔算法的锅炉单相受热管建模与matlab数值仿真.于过热气温控制系统过于复杂,涉及多个过热器及减温过程,在本次设计中将模型简化成喷水减温器和末级过热器的组合,对喷水减温器部分和蒸汽受热管部分进行数学建模,在建模过程中按均匀传热考虑,…

2024-2025-1 20241408陈烨南《计算机基础与程序设计》第十四周学习总结

这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 https://www.cnblogs.com/rocedu/p/9577842.html#WEEK14这个作业的目标 无作业正文 本博客链接教材学习内容总结 无 教材学习中的问题和解决过程 Q:如何倒序输出字符串? A: 基于AI的学习代码调试中…