Codeforces Round 970 (Div. 3) 复盘

news/2024/9/18 13:44:23/文章来源:https://www.cnblogs.com/BigSmall-En/p/18415617

Codeforces Round 970 (Div. 3)

Sep/01/2024 22:35UTC+8 length 02:15

好闲啊,还要写 div3 的复盘,就当听歌的同时练习翻译兼打字了。总而言之还是太菜了

# Who = Penalty * A B C D E F G H
1624 BaSEc1d 6 250 +00:04 +00:19 +00:24 +00:34 +01:17 +01:32

因为开学前几天怕打扰室友睡觉影响人际关系,做完 D 题之后就敲键盘不敢太快了,然后理论上想做完 E 之后就睡,但是发现 F 是水题。

G. Sakurako's Task

给你一个长为 \(n\) 的序列 \(a\),可以选择两个数 \(i,j(i\neq j)\),满足 \(a_i\geq a_j\),然后进行赋值 \(a_i=a_i-a_j\)\(a_i=a_i+a_j\)。可以进行上述操作无数次,要求最大化 \(mex_k\)。其中 \(mex_k\) 是指序列中第 \(k\) 大没有出现的自然数(自然数包括 \(0\))。例如 \(mex_2(\{0,2,4\})=3\)

\(1\leq n\leq 2\times 10^5,1\leq k\leq 10^9\)

显然无论 \(mex_k\)\(k\) 取多少,我们都要尽量让 \(a\) 中元素尽可能小且不重复。

发现如果 \(a\) 中有 \(1\),那么可以将 \(a\) 轻松变成 \({0,1,2,3,4,\dots}\)

我们现在需要判断能不能构造出一个 \(1\) 出来,可以大胆猜测如果 \(a\) 中所有元素的 \(\rm gcd\)\(1\),就能构造出 \(1\) 来。

额我不想证了,因为让我证我估计短时间也证不出来。根据拓展欧几里得,\(ax+by=\gcd(a,b)\) 的解有无数个,似乎就能说明问题。

如果 \(\gcd\) 是其他大于 \(1\) 的数 \(x\),那么则我们只能构造出 \(0,x,2x,3x,\dots\) 来,容易发现这也是这种情况下最优秀的

然后代码就比较好写了

scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
sort(a+1,a+1+n);int minv=__gcd(a[1],a[2]);
if(n==1)goto ptans;
for(int i=3;i<=n;++i)minv=__gcd(minv,a[i]);
a[1]=0;
for(int i=2;i<=n;++i)a[i]=(i-1)*minv;
ptans:
for(int i=1;i<=n;++i){if(a[i]-(i-1)>=k){printf("%d\n",k+i-1-1);goto end;}
}printf("%d\n",k+n-1);
end:;

H. Sakurako's Test

给一个长为 \(n\) 的数组,给出一个数 \(x\),可以进行任意次下列操作

  • 选择一个数 \(i(1\leq i\leq n)\),满足 \(a_i\geq x\)。进行赋值 \(a_i=a_i-x\)

现在想要通过这一操作最小化 \(a\) 数组的中位数。对于每个数组,给 \(q\) 次询问,每次给出一个 \(x\),求出能最小化的中位数的值。(注意如果 \(n\) 是偶数,这里中位数指的是第 \(\frac{n+2}{2}\) 大的数)

\(1\leq \sum n,\sum q\leq 10^5,1\leq a_i\leq n,1\leq x\leq n\)

显然对于每个数,让它尽可能小是最优的,即 \(a_i\to a_i \bmod x\)

那么我们现在要求转换后的数组的中位数,容易发现 \(x\) 的值很多,显然不能每次都暴力转化。

观察题目数据范围,\(1\leq a_i\leq n\),可以考虑将 \(a_i\) 存在桶 \(b_{a_i}\) 内,顺便求一下这个桶的前缀和 \(s\)

因为取模后每个数 \(a_i\in[0,x-1]\),如果在 \([0,x-1]\) 内二分答案,每次求取模后小于等于 \(y\) 的数的个数,则可以在 \(n/x\) 的时间内求出答案(求法就是从头到尾枚举桶每个长度为 \(x\) 的区域(区域首尾相连),该区域内的答案即为该区域前 \(y\) 个桶的总和)。(懒得写数学公式了)

因为我们知道 $\sum_{x=1}^{n} n/x=n\sum_{x=1}^{n} 1/x\approx n\ln n $。所以总的复杂度 \(O(n\log^2n)\)

int n,q,ans[N],a[N],s[N],m,ques[N];
bool check(int lim,int k){int cnt=0;for(int i=0;i<=n;i+=k)cnt+=s[min(i+lim,n)]-(i==0?0:s[i-1]);return cnt>=n/2+1;
}
inline int solve(int k){int l=0,r=k-1,ans=0;while(l<=r){int mid=(l+r)>>1;if(check(mid,k))r=mid-1,ans=mid;else l=mid+1;}return ans;
}
int Test;
int main(){scanf("%d",&Test);while(Test--){scanf("%d%d",&n,&q);for(int i=1;i<=n;++i)a[i]=0,ans[i]=-1;for(int i=1;i<=n;++i){int x;scanf("%d",&x);++a[x];}for(int i=1;i<=n;++i)s[i]=s[i-1]+a[i];for(int i=1;i<=q;++i){scanf("%d",&ques[i]);if(ans[ques[i]]==-1)ans[ques[i]]=solve(ques[i]);}for(int i=1;i<=q;++i)printf("%d ",ans[ques[i]]);puts("");}return 0;
}

A. Sakurako's Exam

给你若干个数,这些数包括 \(a\)\(1\)\(b\)\(2\),你能在这些数前面添加 \(+\)\(-\) 使其和等于 \(0\),问能否做到。

容易发现我们可以只用关注 \(b\)\(2\) 取模的结果,分类讨论即可

m%=2;
if(m){if(n%2==0&&n>=2)puts("YES");else puts("NO");
}else{if(n%2==0)puts("YES");else puts("NO");
}

B. Square or Not

一个漂亮的 \(01\) 矩阵是指数字 \(1\) 全在其外围而数字 \(0\) 全在其内部

img

现在将一个漂亮的 \(01\) 矩阵的字符串形式告诉你,问这个漂亮的 \(01\) 矩阵是否是一个正方形。对于一个大小为 \(r\times c\) 的矩阵,他的字符串 \(s\) 的第 \(((i-1)\times c+j)\) 个元素对应矩形的第 \(i\) 行第 \(j\) 列的元素。

做的时候还把题目看复杂了,以为要判断这个矩阵是不是漂亮的。

容易发现连续的 \(0\) 的数量 \(+2\) 就是这个矩阵的列数,除一下算出行数判断即可。

C. Longest Good Array

一个长为 \(n\) 的数列被认为是好的当且仅当

  • 这个数列是递增的,即 \(a_{i-1}<a_i(2\leq i\leq n)\)
  • 两个连续数的差也是递增的,即 \(a_i-a_{i-1}<a_{i+1}-a_i(2\leq i<n)\)

现在一直一个好的数列的元素都在 \([l,r]\) 之间,求这个好的数列的最长长度 \((1\leq l\leq r\leq 10^9)\)

显然第一个元素为 \(l\) 是最优秀的,然后按照题意模拟求下一项即可,这是个二次等差数列,第 \(n\) 个数数量级 \(n^2\),足以通过此题。当然也可以求通项再做。

ll l,r;scanf("%lld%lld",&l,&r);
ll v=l,cnt=0;
while(v<=r){++cnt;v+=cnt;
}
printf("%lld\n",cnt);

D. Sakurako's Hobby

给定一个排列 \(p\),称一个数 \(j\) 能够从 \(i\) 到达当且仅当可以通过数次 \(i=p_i\) 操作让 \(i\) 等于 \(j\)。排列中的每个数为白色或黑色。定义函数 \(f(i)\) 表示从 \(i\) 可以到达的黑色的数的个数。现在求每个数的 \(f(i)\)

非常典,对 \(i\to p_i\) 连边,可以发现会形成若干个环。\(f(x)\) 就是 \(x\) 所在环中黑色数的个数。实现的话循环染色即可。

int n;scanf("%d",&n);
for(int i=1;i<=n;++i){scanf("%d",&p[i]);vis[i]=vb[i]=ans[i]=0;
}scanf("%s",s+1);
for(int i=1;i<=n;++i){int loc=i,cnt=0;while(!vis[loc]){vis[loc]=1;if(s[loc]=='0')++cnt;loc=p[loc];}loc=i;while(!vb[loc]){vb[loc]=1;ans[loc]=cnt;loc=p[loc];}
}
for(int i=1;i<=n;++i){printf("%d ",ans[i]);
}puts("");

E. Alternating String

如果一个长度为偶数的字符串奇数位的字符相同,偶数位上的字符相同,则称这个字符串为交错串。现在给你一个字符串,求最少通过下列多少次操作可以使字符串变为交错串。

  1. 删去字符串中的一个字符,字符串的长度 \(-1\)。注意:该操作最多只能进行一次。
  2. 选择一个字符将其修改为其他字符。

字符只能包括小写字母。

显然长度为偶数的字符串不进行操作1;长为奇数的字符串必须要进行一次操作1转化为偶数串,并且最先进行操作1不会使答案更劣。

先考虑偶数怎么做,偶数位和奇数位可以分开考虑,对于每种位,将其位上的字符变成这种位上出现次数最多的字符显然最优。开两个桶分别求 \(26\) 种字母在奇数位和偶数位上出现的次数即可。

在考虑奇数怎么做,枚举删除字符的位置,在像偶数做法一样求是 \(O(n^2|S|)\) 的。

可以考虑将删去字符之前的桶和之后的桶整合。考场做法是开一个 \(dp_{i,c,0/1}\) 表示前 \(2\times i\) 个字符中字符 \(c\) 在偶数或奇数位出现的次数(这就是一个前缀和)。

int ans=n,mv1=0,mv2=0;
for(int i=1;i<=n/2;++i){mv1=0,mv2=0;for(int j=0;j<26;++j){mv1=max(mv1,dp[i-1][j][0]+(dp[n/2][j][1]-dp[i-1][j][1]));mv2=max(mv2,dp[i-1][j][1]+(dp[n/2+1][j][0]-dp[i][j][0]));}ans=min(ans,n-mv1-mv2);mv1=0,mv2=0;for(int j=0;j<26;++j){mv1=max(mv1,dp[i][j][0]+(dp[n/2][j][1]-dp[i][j][1]));mv2=max(mv2,dp[i-1][j][1]+(dp[n/2+1][j][0]-dp[i][j][0]));}ans=min(ans,n-mv1-mv2);
}
mv1=0,mv2=0;
for(int j=0;j<26;++j){mv1=max(mv1,dp[n/2][j][0]);mv2=max(mv2,dp[n/2][j][1]);
}
ans=min(ans,n-mv1-mv2);

现在突然发现可以在枚举断点时就顺带维护前后的桶,码量小而且细节少(没想到复盘这些水题还有一些收获)

int ans=n;
for(int i=1;i<=n;++i)bot[s[i]-'a'][i&1]++;
for(int i=1;i<=n;++i){int mv1=0,mv2=0;--bot[s[i]-'a'][i&1];for(int j=0;j<26;++j){mv1=max(mv1,bot2[j][1]+bot[j][0]);mv2=max(mv2,bot2[j][0]+bot[j][1]);}ans=min(ans,n-mv1-mv2);++bot2[s[i]-'a'][i&1];
}
printf("%d\n",ans);

F. Sakurako's Box

给你 \(n\) 个数,求随机去两个数相乘,这个积的期望。

感觉比 E 思维难度小,而且没啥码量,就上床前顺带做了。

求出所有数对的积的和然后除以数对的个数即为期望。定义所有数的和为 \(s\),数对的积的和就是 \(\frac{1}{2}\times\sum a_i\times (s-a_i)\),数对的个数显然 \(\frac{n\times(n-1)}{2}\),求一下逆元即可。

scanf("%d",&n);
ll sum=0,ans=0;
for(int i=1;i<=n;++i){scanf("%lld",&a[i]);sum=(sum+a[i])%P;
}
for(int i=1;i<=n;++i)ans=(ans+a[i]*(sum-a[i]+P)%P)%P;
ans=ans*fpr(2)%P;
printf("%lld\n",ans*fpr(n)%P*fpr(n-1)%P*2%P);

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

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

相关文章

2024年7连测第二场

A link如果想要\(x_1+y_2=x_2+y_1\),就是\(x_1-x_2=y_1-y_2\)即可,那么我们可以存一下每一个\(i\)的\(x\)与\(y\)的差,每到一个\(i\)就看一下前面有几个的差和它相等,这一个就可以和多少个组上对。点击查看代码 #include<bits/stdc++.h>using namespace std;int n,an…

AI老照片修复神器,Anole下载介绍

最近AI老照片修复上色,再一次火出圈,一些社交平台关于此话题内容流量满满,尤其是在小红书和抖音火的不得了,本期文章就来给大家分享下AI修复老照片的方式方法 本文主要介绍使用Anole修复老照片的方法,只需输入一张黑白或彩色照片,即可得到修复后的彩色结果,让往日的老照…

肖健飞的第一次作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/zjlg/rjjc这个作业的目标 进行自我评估,熟悉博客园的使用方法,阐述自己的课程期望姓名-学号 肖健飞-2022329301124一、自我介绍 (一)基本情况及爱好 我叫肖健飞,来自江苏泰州,是信息科学与工程学院22级自动化(2)班…

2024ICPC网络赛第一场题解(部分)

2024ICPC网络赛第一场题解和参考代码以及部分思路说明这一场基本纯挂件,给队友翻译翻译题面,帮队友打打板子了,可惜最后40sL题冲了一个 \(O(\frac{n^3}{w})\) 的bitset最后wa了,所以下面的题解我也只能看着队友代码说说大概,主要参考一下代码吧。 A 题意 给出32个队伍的能…

sign与unsigned的原理、数据存储与硬件的关系

目录关键字unsigned和signed数据在计算机中的存储原码 与 补码的转化与硬件关系原,反,补的原理:整型存储的本质变量存取的过程类型目前的作用十进制与二进制快速转换大小端字节序判断当前机器的字节序"负零"(-128)的理解截断建议在无符号类型的数值后带上u, 关键字un…

C++中对象的延迟构造

本文并不讨论“延迟初始化”或者是“懒加载的单例”那样的东西,本文要讨论的是分配某一类型所需的空间后不对类型进行构造(即对象的lifetime没有开始),更通俗点说,就是跳过对象的构造函数执行。 使用场景 我们知道,不管是定义某个类型的对象还是用operator new申请内存,…

黑客失误?76.2万车主,家庭住址信息泄露

​据Cybernews研究团队发现,一个包含76.2W名车主及其车辆详细信息的敏感数据库已经在网上泄露。这些数据托管在一个美国的IP地址上,首次发现是在8月4日,至少暴露了48小时。据该团队称,泄露的数据揭示了车主的敏感信息。泄露的细节几乎揭示了拥有车辆的个人的所有信息,包括…

C++ 在 Visual Studio 如何将指针星号设置成靠近变量而不是类型

“工具”->“选项”->“文本编辑器”->“C/C++”->“代码样式”->“格式设置”->“间距”->“指针/引用对齐方式”->“右对齐”。

Git冲突解决技巧

在多人协作的软件开发项目中,Git 冲突是不可避免的现象。当两个或更多的开发者同时修改了同一段代码,并且尝试将这些修改合并到一起时,冲突就发生了。解决这些冲突是确保代码库健康和项目顺利进行的关键。在多人协作的软件开发项目中,Git 冲突是不可避免的现象。当两个或更…

AI写作助手哪些好用?6款强大的AI写作助手值得收藏!

在内容创作日益重要的今天,AI写作助手已经成为许多创作者的得力工具。它们不仅能够提高写作效率,还能在一定程度上保证文章质量。面对市场上琳琅满目的AI写作助手,如何选择一款好用且适合自己的工具呢?以下推荐6款强大的AI写作助手,它们各具优势,助力创作者轻松应对各种写…

1928.规定时间内到达终点的最小话费,题解

1928. 规定时间内到达终点的最小花费 - 力扣(LeetCode) 有点难,参考官方题解代码: 利用了动态规划思想,逐步计算从起点到各个城市在不同时间下的最小费用。 1.代码解释,涉及,static关键字,constexpr关键字,INT_MAX除以2赋值的含义static constexpr int INFTY = INT_MA…