ABC392
终于进前一千了。
A - Shuffled Equation
人话:给定三个数 \(a,b,c\),判断是否存在两个数乘积为第三个数。
数很小,if 判断一下,long long 也不用开。
点击查看代码
#include <iostream>
#include <cstdio>
using namespace std;
int a,b,c;
int main(){
cin>>a>>b>>c;
if(a*b==c)cout<<"Yes"<<endl;
else if(b*c==a)cout<<"Yes"<<endl;
else if(c*a==b)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
时间复杂度 \(O(1)\)。
B - Who is Missing?
注意到值域很小,我们开一个桶。如果 \(i\) 出现过,则 \(f_i\) 为 \(1\),反之为 \(0\)。
然后按照 \(1\sim n\) 的顺序检查那个桶里没数就行。
点击查看代码
#include <iostream>
#include <cstdio>
using namespace std;
int n,m,x,t[1005],cnt;
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++)cin>>x,t[x]++;
for(int i=1;i<=n;i++)if(!t[i])cnt++;
cout<<cnt<<endl;
for(int i=1;i<=n;i++)if(!t[i])cout<<i<<" ";
return 0;
}
时间复杂度 \(O(n)\)。
C - Bib
挺绕的。
每个人有三个属性,编号,牌子(也就是 \(p_i\)),看的人的编号(也就是 \(q_i\))。
假设 \(s_i\) 表示牌子上的数位 \(i\) 的人的编号。这个可以预处理建立映射关系。
那么根据定义,牌子为 \(i\) 的人编号为 \(s_i\),看的人的编号为 \(q_{s_i}\),看的人挂的牌子为 \(p_{q_{s_i}}\)。
主要是搞清楚编号,牌子,看的人之间的关系即可。
点击查看代码
#include <iostream>
#include <cstdio>
using namespace std;
const int N=3e5+10;
int n,p[N],q[N],s[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",q+i);
}
for(int i=1;i<=n;i++){
scanf("%d",s+i);
p[s[i]]=i;
}
for(int i=1;i<=n;i++){
printf("%d ",s[q[p[i]]]);
}
return 0;
}
时间复杂度 \(O(n)\)。
D - Doubles
咋还卡人精度呢?
先思考暴力,枚举两个骰子 \(i,j\),枚举摇出来的数 \(x\),则答案就是:
\]
\]
\(cnt_{i,j}\) 表示骰子 \(i\) 有多少个面是 \(j\),上面的式子根据乘法原理和加法原理易得。
暴力会超时,注意值域很小,我们先枚举 \(i\),然后开一个桶 \(t_j\) 表示骰子 \(i\) 有多少个面为 \(j\)。
接着我们枚举每一个 \(j<i\),分别计算 \(i,j\) 的答案,具体做法是遍历 \(j\) 骰子的每一个面 \(x\),然后让答案 \(ans\) 加上 \(t_x\)。最后 \(\frac{ans}{k_ik_j}\)。
枚举 \(i\) 是 \(O(n)\) 的,枚举每一个骰子 \(i\) 的面是 \(K_i\),枚举 \(j\),枚举 \(j\) 骰子的每一个面可以看成一个整体,是 \(O(S-K_i)\) 的,其中 \(S=\sum K_i\),意思是最多会将除了骰子 \(i\) 以外其他所有骰子的所有面都遍历一遍。
容易发现后两步合起来是 \(O(S)\)。这样做复杂度均摊下来是正确的。
点击查看代码
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int N=1e5+10;
vector<int>v[105];
int n;
long long k[105],cnt[N];
long double res,ans;
long double fmax(long double a,long double b){
return a<b?b:a;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",k+i);
for(int j=1,x;j<=k[i];j++){
scanf("%d",&x);
v[i].push_back(x);
}
}
for(int i=2;i<=n;i++){
for(auto u:v[i])cnt[u]++;
for(int j=1;j<i;j++){
res=0;
for(auto u:v[j])res=(double)(res+cnt[u]);
res=(long double)(res/(k[i]*k[j]));
ans=max(ans,res);
}
for(auto u:v[i])cnt[u]--;
}
printf("%.12LF\n",ans);
return 0;
}
时间复杂度 \(O(nS)\)。
E - Cables and Servers
小清新题。
注意到 \(M\ge N-1\),也就是说无论如何我们也可以给所有边的两个端点重新编号,让他联通。
我们先把原图建出来,这样的图是若干个不连通的图。在原图中,有一些边是无关紧要的,去掉这一条边对原图联通性没有影响。我们可以用这些边来连接其他的联通块。
我们思考这样一个过程:划分联通块,然后找出每个联通块有多少个无用的边,统计当前那个联通块 \(u\) 无用边最多,那个联通块 \(v\) 无用边次多,将 \(u\) 内的一条无用边的一个端点改到 \(v\) 上的端点,此时 \(u,v\) 就被合并了,\(v\) 的无用边也变成了 \(u\) 的无用边。因为 \(M\ge N-1\),所以除了这个图仅剩一个联通块的情况,无论何时都有无用边。
容易发现,此时 \(u,v\) 合并后的联通块又成为了无用边最多的联通块,假设有 \(k\) 个联通块,我们按照每个联通块内部无用边多少排序,然后依次将 \(2\sim k\) 的联通块和 \(1\) 合并,这个算法就是正确的,容易发现,这样的操作此时为 \(k-1\)。
考虑构造方案,我们把每个联通块排好序后,将每个联通块内的无用边按照同样顺序放进数组里,然后从前往后一条一条边的用即可。
点击查看代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int N=2e5+10;
int n,m,a[N],b[N],f[N],rt[N],k,rest[N],p,mk[N];
vector<int>vec[N];
int found(int x){
return f[x]==x?x:f[x]=found(f[x]);
}
bool cmp(int a,int b){
return vec[a].size()>vec[b].size();
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=m;i++){
scanf("%d %d",a+i,b+i);
int u=found(a[i]);
int v=found(b[i]);
if(u!=v)f[u]=v;
else mk[i]=1;
}
for(int i=1;i<=m;i++)if(mk[i])vec[found(a[i])].push_back(i);
for(int i=1;i<=n;i++)if(found(i)==i)rt[++k]=i;
printf("%d\n",k-1);
sort(rt+1,rt+1+k,cmp);
for(int i=1;i<=k;i++)for(auto j:vec[rt[i]])rest[++p]=j;
for(int i=2;i<=k;i++){
printf("%d %d %d\n",rest[i-1],a[rest[i-1]],rt[i]);
}
return 0;
}
时间复杂度 \(O(n\log n)\)。
F - Insert
平衡树板子,蚌埠住了。
考虑无旋 treap(FHQ treap),每个节点上维护一个权值,和子树的大小,插入第 \(i\) 个数时,假设这个数排名为 \(k\)。split 时,将平衡树分成两颗大小分别为 \(k-1\) 和 \(i-k\) 两颗平衡树,merge 时把新建的节点夹在中间合并即可,时间复杂度 \(O(n\log n)\)。
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int N=5e5+10;
int tot,root,n;
struct node{
int l,r,size,dat,val;
}a[N];
int New(int s){
a[++tot].val=s;
a[tot].size=1;
a[tot].dat=rand();
return tot;
}
void update(int p){
a[p].size=a[a[p].l].size+a[a[p].r].size+1;
}
void split(int p,int k,int &x,int &y){
if(!p)return x=y=0,void();
else if(a[a[p].l].size+1<=k)split(a[p].r,k-a[a[p].l].size-1,a[x=p].r,y);
else split(a[p].l,k,x,a[y=p].l);
update(p);
}
int merge(int x,int y){
if(!x||!y)return x+y;
if(a[x].dat>a[y].dat)return a[x].r=merge(a[x].r,y),update(x),x;
else return a[y].l=merge(x,a[y].l),update(y),y;
}
void insert(int s,int k){
int x=0,y=0;
split(root,k-1,x,y);
root=merge(merge(x,New(s)),y);
}
void print(int p){
if(!p)return;
print(a[p].l);
printf("%d ",a[p].val);
print(a[p].r);
return;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int p;
scanf("%d",&p);
insert(i,p);
}
print(root);
return 0;
}
多的可以去看平衡树模板。
G - Fine Triplets
好好好,都会 FFT/NTT 是吧。
首先 \(B-A=C-B\) 可以写作 \(2B=A+C\),所以我们只需要求出有多少个数对 \((A,C)\) 和为 \(2B\)。
我们不妨开一个桶 \(t\),\(t_x\) 表示 \(S\) 中 \(x\) 的出现次数。记 \(m=2B\),上面说的这个问题答案即为 \(\sum_{i=1}^{m-1}t_it_{m-i}\) 的一半(因为求得是无序数对)。
这个玩意不就是一个卷积吗,FFT/NTT 可以 \(O(n\log n)\) 求出来。
?这不是卷积模板吗。
好吧,我不会卷积。。。
随机推荐
- 能用 Java8 开发 MCP(或 MCP Server),这才是 MCP 自由(Solon AI MCP)!
现在,用 Java 开发 MCP 的情况是: 框架 JDK要求 mcp-sdk 需要 jdk17+ spring-ai-mcp-server 需要 jdk17 + spring-ai-mcp-clie ...
- Python实验3 函数与代码复用
目的:理解函数封装与递归思想 实验任务: 基础 :编写函数cal_factorial(n)计算阶乘(循环实现). 源码: def cal_factorial(n): result = 1 for i ...
- Elasticsearch7.6.1配套安装包自取
包含Elasticsearch,ik分词器,kibana 7.6.1安装包自取:https://pan.baidu.com/s/1Y6XdDOzqIzI2qerOODQHmg提取码:5nm4
- 通用型产品发布解决方案(SpringBoot+SpringCloud+Spring CloudAlibaba+Vue+ElementUI+MyBatis-Plus+MySQL+Git+Maven)03
通用型产品发布解决方案(基于分布式微服务技术栈:SpringBoot+SpringCloud+Spring CloudAlibaba+Vue+ElementUI+MyBatis-Plus+MySQL+ ...
- GoView:Start14.6k,上车啦上车啦,Vue3低代码平台GoView,零代码+全栈框架
GoView:Start14.6k,上车啦上车啦,Vue3低代码平台GoView,零代码+全栈框架 项目介绍 GoView 是一个Vue3搭建的低代码数据可视化开发平台,将图表或页面元素封装为基础组件 ...
- SpringBoot静态资源访问--转载
转载地址:https://www.jianshu.com/p/d40ee98b84b5
- GUI development with Rust and GTK4 阅读笔记
简记 这是我第二次从头开始阅读,有第一次的印象要容易不少. 如果只关心具体的做法,而不思考为什么这样做,以及整体的框架,阅读的过程将会举步维艰. 简略记录 gtk-rs 的书中提到的点.对同一个问题书 ...
- SQL 强化练习 (七)
继续 sql 练习, 不能停下来的哦, 通过这一系列的搬砖操作, 相信在日常业务的sql 应该是能达到相对清楚地写出来的, 尤其是我做数据分析这块, 感觉真的每天都要写才行, 之前都是用 Python ...
- CentOS 7.6安装nginx
1.安装EPEL仓库 [root@ecs-lanxinmeichen nginx]# sudo yum install epel-releaseLoaded plugins: fastestmirro ...
- TVM Pass优化 -- 移除无用函数(Remove Unused Function)
定义 移除无用函数,Remove Unused Function,顾名思义,就是删除Module中定义但未用到的函数 当然,它也是一个模块级的优化, 举例子: def get_mod(): mod = ...