前言

比赛链接:

Div.1 : http://47.110.12.131:9016/contest/7

Div.2 : http://47.110.12.131:9016/contest/8

Div.2——四月是你的谎言

下面是 Div.2 的题解。

A. 若能绽放光芒

首先讲一个 \(\Theta(n^3)\) 的暴力:

枚举区间 \([l,r]\),这里已经有 \(\Theta(n^2)\) 的时间复杂度了。

然后我们考虑怎么找到这段区间对应的最长公共“子序列”。

这个贪心一下,找到从左到右的第一个下一个字母,\(\Theta(n)\) 匹配即可,这里有 \(\Theta(n)\) 的时间复杂度。

故总的时间复杂度是 \(\Theta(n^3)\)。

接着讲一下 \(\Theta(n^2)\) 的做法:

实际上你会发现上面那个是增量构造,对此我们可以优化。

考虑固定左端点,右移右端点,这样可以省去一维的复杂度。

于是就优化成了 \(\Theta(n^2)\) 的时间复杂度,即可通过本题。

  1. for(Re int i=1;i<=n;i++)
  2. {
  3. int k=0;
  4. for(Re int j=i;j<=n;j++)
  5. {
  6. while(k<=m&&b[k]!=a[j])
  7. {
  8. k++;
  9. }
  10. if(k>m)
  11. {
  12. ans=min(ans,j-i+1);
  13. break;
  14. }
  15. k++;
  16. }
  17. }

B. 七色交响曲

对于 \(30\%\) 的数据,我们考虑对 \(n\) 个物品枚举它们属于的容器情况即可,时间复杂度大约为 \(\Theta(n!)\)。

对于 \(60\%\) 的数据,我们换个更优秀的搜索策略,并加上记忆化

考虑 \([l,r]\) 区间最优怎么算,我们枚举它中间的断点,把这个区间分成两块处理,也就是所谓的分治

它的思想就是来源于搜索,于是我们考虑在分治过程中加上记忆化数组。

这样,它的时间复杂度为 \(\Theta(n^3)\)。

对于 \(100\%\) 的数据,我们考虑这样一个动态规划想法:

如果想到了上面的记忆化搜索思想,那这题的动态规划思路应该还是很好想的。

设 \(f[i]\) 表示将 \(1\) 至 \(i\) 的物品都放入容器中的最小费用。

我们考虑枚举一个 \(j\) 来进行转移,具体状态转移方程如下:

\[f[i]=\min_{0\leq j<i}\{f[j]+(\sum_{k=j+1}^{i}l[k]+i-j-1-p)^{2}\}
\]

设 \(l\) 的前缀和数组为 \(s\) ,即 \(s[i]=\sum\limits_{k=1}^{i}l[k]\) ,那么方程就变为如下形态:

\[f[i]=\min_{0\leq j<i}\{f[j]+(s[i]-s[j]+i-j-1-p)^{2}\}
\]

此时我们暴力去做,时间复杂度为 \(O(n^2)\),即可通过本题。

  1. memset(dp,127/3,sizeof dp);
  2. dp[0]=0;
  3. for(Re int i=1;i<=n;i++)
  4. {
  5. for(Re int j=0;j<i;j++)
  6. {
  7. dp[i]=min(dp[i],dp[j]+(s[i]-s[j]+i-j-1-p)*(s[i]-s[j]+i-j-1-p));
  8. }
  9. }

C. 闪耀

为了方便起见,下面设题目中的两人为甲、乙。

设投票记录用 \(m+n\) 元有序组 \((a_1,a_2,...,a_{m+n})\) 表示。

当第 \(1\leq k\leq m+n\) 次唱票时,如果选票为甲,则 \(a_k=1\),否则 \(a_k=-1\)

令 \(b_k=\sum\limits_{i=1}^{k}a_i\),然后考虑用折线法来求解。

从左到右连接以下格点:\((1,b_1),(2,b_2),...,(m+n,b_{m+n})\),得到一条 \(m+n-1\) 节的折线。

因为甲的票数一直领先,所以 \(\forall k,b_k>0\),且 \(b_1=1,b_{m+n}=m-n\)

换句话说,这是一条连接 \((1,1)\) 与 \((m+n,m-n)\) 且与 \(x\) 轴没有交点的折线。

由简单的数学知识可知:这种折线数目为 \(\begin{aligned} \text{C}_{m+n-1}^{m-1}-\text{C}_{m+n-1}^{m}=\frac{m-n}{m+n}\text{C}_{m+n}^{m} \end{aligned}\)

直接预处理逆元后输出即可,时间复杂度 \(\Theta(n)\)。

  1. int ans=1;
  2. ans=(1ll*ans*inv[m+n])%mod;
  3. ans=(1ll*ans*(m-n))%mod;
  4. for(Re int i=1;i<=m;i++)
  5. {
  6. ans=(1ll*ans*inv[i])%mod;
  7. ans=(1ll*ans*(m+n-i+1))%mod;
  8. }

D. 橘黄

搜索即可,你们不是刚刚学了搜索吗???

直接枚举每种情况,然后算答案即可,时间复杂度约为 \(\Theta(n!)\)。

由于这种做法比较简单,更优的做法代码放在 Div.2 的 D 题中。

E. 爱之忧伤

对于 \(20\%\) 的数据,我们考虑枚举两个点 \(i,j\) 后暴力跳 LCA 来求 \(f(i,j)\),时间复杂度为 \(\Theta(n^3)\)

对于 \(50\%\) 的数据,我们在跳 LCA 的时候考虑 倍增/重链剖分/Tarjan 来优化它,时间复杂度可以做到 \(\Theta(n^2\log n)\)

对于 \(100\%\) 的数据,我们换一个思路:

对于每个点,看看它是哪些点对的 LCA,然后只要考虑每个点这样的贡献,最后把它们求和。

具体来说,我们枚举一个 \(i\),记录下以 \(i\) 为根的子树大小,然后直接用这个计算即可。

时间复杂度为 \(\Theta(n)\)

  1. inline void dfs(int u,int f)
  2. {
  3. sz[u]=1;
  4. for(Re int i=0;i<T[u].size();i++)
  5. {
  6. int v=T[u][i];
  7. if(v==f) continue;
  8. dfs(v,u);
  9. ans=(ans+a[u]*(1ll*sz[u]*sz[v]%mod)%mod)%mod;
  10. sz[u]+=sz[v];
  11. }
  12. }

Div.1——末日三问

下面是 Div.1 的题解。

A. Always in my heart

我们考虑把每个位置连一条指向下一个 \(\text{a}\) 至 \(\text{z}\) 的边,这样形成的图叫作子序列自动机

所以用 \(\Theta(n |\Sigma|)\) 的时间建出来,再用 \(\Theta(n)\) 的时间枚举一遍,然后就做完了。

  1. f[0][0]=0;
  2. for(Re int i=0;i<=m;i++)
  3. {
  4. for(Re int k=0;k<26;k++)
  5. {
  6. if(pntB[i][k]!=-1)
  7. {
  8. for(Re int j=0;j<=n;j++)
  9. {
  10. if(pntA[j][k]!=-1)
  11. {
  12. f[pntB[i][k]][pntA[j][k]]=min(f[pntB[i][k]][pntA[j][k]],f[i][j]+1);
  13. }
  14. }
  15. }
  16. else
  17. {
  18. for(Re int j=0;j<=n;j++)
  19. {
  20. if(pntA[j][k]!=-1)
  21. {
  22. ans=min(ans,f[i][j]+1);
  23. }
  24. }
  25. }
  26. }
  27. }

B. Ever be my love

我们考虑把 Div.3 的那个式子优化成 \(\Theta(n)\),而这要用到斜率优化的内容,可以学一学,详见:

https://www.cnblogs.com/kebingyi/p/14157680.html

C. Chtholly Nota Seniorious

本题与 Div.3 的 C 题类似,读者可不妨自行推导出这样的式子:

\[ans=\frac{m}{m+n}\text{C}_{m+2n-1}^{n}
\]

同样,我们直接求解即可。

  1. int ans=1;
  2. ans=(1ll*ans*inv[m+n])%mod;
  3. ans=(1ll*ans*m)%mod;
  4. for(Re int i=1;i<=n;i++)
  5. {
  6. ans=(1ll*ans*inv[i])%mod;
  7. ans=(1ll*ans*(m+n+n-i))%mod;
  8. }

D. Scarborough Fair

很妙的!

这个搜索类似于上面 Div.3 的 B 题中 \(60\%\) 部分分的形式。

我们以几乎同样的思路再做一遍就不难得出正解,具体的由场切的 chenxulei 大佬来讲解吧!

其实这个题是 IOI2020 国家集训队作业的原题,有能力的同学可以考虑刷一刷这个。

  1. LL dfs(int L,int R,LL x,LL y)
  2. {
  3. if(L>R) return 0;
  4. LL ret=1e17;
  5. for(Re int i=L;i<=R;i++)
  6. {
  7. ret=min(ret,dfs(L,i-1,x,x+y)+dfs(i+1,R,x+y,y)+a[i]*(x+y));
  8. }
  9. return ret;
  10. }

E. 最幸福的女孩

大家知道那个 \(O(n\ln n)\) 求数论函数的技巧吗?

不知道的话可以学学,看如下标程:

  1. for (Re int i = 1, j; i < maxn; i++)
  2. for (Re int j = 1; j * i < maxn; j++)
  3. (f[i * j] += g[i] * 1ll * phi[j] % mod * mu[pi[i]] % mod) %= mod;

这么做看着是 \(O(n^2)\) 的,其实是 \(O(n\ln n)\) 的,至于为什么就自己去学学吧……

然后前缀和一下:

  1. for (Re int i = 1; i < maxn; i++) (f[i] += f[i - 1]) %= mod;

这样就可以 \(O(1)\) 查询了。

YAOI Round #3 题解的更多相关文章

  1. YAOI Round #7 题解

    前言 比赛链接: Div.1 : http://47.110.12.131:9016/contest/16 Div.2 : http://47.110.12.131:9016/contest/15 D ...

  2. YAOI Round #5 题解

    前言 比赛链接: Div.1 : http://47.110.12.131:9016/contest/13 Div.2 : http://47.110.12.131:9016/contest/12 D ...

  3. YAOI Round #1 题解

    前言 比赛网址:http://47.110.12.131:9016/contest/3 总体来说,这次比赛是有一定区分度的, \(\text{ACM}\) 赛制也挺有意思的. 题解 A. 云之彼端,约 ...

  4. Codeforces Round #556 题解

    Codeforces Round #556 题解 Div.2 A Stock Arbitraging 傻逼题 Div.2 B Tiling Challenge 傻逼题 Div.1 A Prefix S ...

  5. LibreOJ β Round #2 题解

    LibreOJ β Round #2 题解 模拟只会猜题意 题目: 给定一个长为 \(n\) 的序列,有 \(m\) 次询问,每次问所有长度大于 \(x\) 的区间的元素和的最大值. \(1 \leq ...

  6. Codeforces Round #569 题解

    Codeforces Round #569 题解 CF1179A Valeriy and Deque 有一个双端队列,每次取队首两个值,将较小值移动到队尾,较大值位置不变.多组询问求第\(m\)次操作 ...

  7. Codeforces Round #557 题解【更完了】

    Codeforces Round #557 题解 掉分快乐 CF1161A Hide and Seek Alice和Bob在玩捉♂迷♂藏,有\(n\)个格子,Bob会检查\(k\)次,第\(i\)次检 ...

  8. CFEducational Codeforces Round 66题解报告

    CFEducational Codeforces Round 66题解报告 感觉丧失了唯一一次能在CF上超过wqy的机会QAQ A 不管 B 不能直接累计乘法打\(tag\),要直接跳 C 考虑二分第 ...

  9. Google kickstart 2022 Round A题解

    Speed Typing 题意概述 给出两个字符串I和P,问能否通过删除P中若干个字符得到I?如果能的话,需要删除字符的个数是多少? 数据规模 \[1≤|I|,|P|≤10^5 \] 双指针 设置两个 ...

随机推荐

  1. Python - random 库的详细使用

    前言 为啥突然写这个?因为用到就写呗,感觉对生成数据很有用,之前都是百度别人的,今天来对着官方文档写,超级标准! 这边只讲常用的,看了下文档还有什么数学方法,太高级好像用不上 返回整数 random. ...

  2. IDEA2021.1 安装教程

    工欲善其事必先利其器. 一.下载 IDEA 官方下载地址: https://www.jetbrains.com/zh-cn/idea/download/ 二.安装 IDEA 注:安装IDEA之前需要我 ...

  3. gin框架路由拆分与注册

    gin框架路由拆分与注册 本文总结了我平时在项目中积累的关于gin框架路由拆分与注册的若干方法. gin框架路由拆分与注册 基本的路由注册 下面最基础的gin路由注册方式,适用于路由条目比较少的简单项 ...

  4. openresty 学习笔记番外篇:python的一些扩展库

    openresty 学习笔记番外篇:python的一些扩展库 要写一个可以使用的python程序还需要比如日志输出,读取配置文件,作为守护进程运行等 读取配置文件 使用自带的ConfigParser模 ...

  5. h264和h265多维度区别

    h264和h265多维度区别 1.  概述 h265旨在在有限带宽下传输更高质量的网络视频,仅需原先的一半带宽即可播放相同质量的视频,很多朋友不知道h264和h265如何区别,下面让我们一起来了解一下 ...

  6. onnx算子大全

    本文通过此脚本从def文件自动生成.不要直接修改,而是编辑算子定义. 对于算子输入/输出的可辩别的,它可以是可辩别的.不可辩别的或未定义的.如果未指定变量的可辩别的,则该变量具有未定义的可辩别的. a ...

  7. 如果在num1的任何位置有一个数字的连续三倍,并且在num2中有一个数字的连续两倍,则返回1。 如果不是这样,则返回0

    ''' 它接受数字num1和num2,如果在num1的任何位置有一个数字的连续三倍,并且在num2中有一个数字的连续两倍,则返回1. 如果不是这样,则返回0 例子 triple_double(4519 ...

  8. .NET平台系列30:.NET Core/.NET 学习资源汇总

    系列目录     [已更新最新开发文章,点击查看详细] .NET Core/.NET技术虽然吸取了.NET Framework 中的精华,但是也扩展了一些新功能,尤其是跨平台的 ASP.NET Cor ...

  9. 数据库创建好之后如何创建scott用户

    SQL> conn / as sysdba Connected. SQL> @%oracle_home%\rdbms\admin\utlsampl.sql 建立完成以后会自动退出sqlpl ...

  10. 实现SLIC算法生成像素画

    前言 像素风最早出现在8bit的电子游戏中,受制于电脑内存大小以及显示色彩单一, 只能使用少量像素来呈现内容,却成就了不少经典的像素游戏.随着内存容量与屏幕分辨率的提升,内存与显示媒介的限制不再是问题 ...