20221013模拟赛题解
改题比赛
A-record
先将原图按颜色划分成多个大小至少为 的连通块,不难发现每个连通块内的颜色永远一样,然后对于每个连通块向外 bfs 扩展,每个点第一次被扩展到后颜色就会开始变化。所以记录一下每个点什么时候被扩展到以及它会跟随哪个连通块,然后询问时判一下时间和奇偶性即可。
B-jewelry
分析
发现 很大,而 很小,于是可以开个桶存每个 对应的 的集合。此时很显然可以设 表示枚举到售价为 ,花了 元的最大吸引力,转移方程就呼之欲出了:
,其中 表示售价为 的前 大吸引力之和。此时暴力 dp 的复杂度是 ,能获得 的好成绩。
考虑优化,发现其贡献函数的增长率随 增大而而减小,即其二阶导恒为非正,且题目中求的是最大值,因此其满足决策单调性。
因此可以使用分治或二分队列等常见做法优化到 。
C-impression
分析
首先发现一个显然的结论,把树分成若干份权值和相等的连通块要么没有方案要么只有 种方案。
然后发现每块权值分 时,一个节点 能和其父节点断开的必要条件是 。于是可以设
,其中 表示以 为根的子树大小。
考虑如何计算 ,发现若 里算进去了 ,设 则必有
,于是有
,于是每次枚举倍数即可。这部分的复杂度相当于是 。
发现树能合法地分成 份当且仅当 ,举几个例子能容易发现。
再考虑整体的答案,设 表示最后一次分成 份的方案数,发现每次分的份数一定是上一次的倍数,于是转移还是个 ,转移方程为:
,最后输出 求和即可。
核心代码
int n,a[MAXN],f[MAXN],dp[MAXN],s[MAXN],ans;vector<int>d[MAXN],tr[MAXN];
void dfs(int u,int fa){
s[u]=a[u];for(auto v:tr[u]) if(v!=fa) dfs(v,u),s[u]+=s[v];
}int gcd(int x,int y){return y?gcd(y,x%y):x;}
signed main(){
qread(n);int i,j;for(i=1;i<=n;i++) qread(a[i]);
for(i=2;i<=n;i++){
int p;qread(p);
tr[i].push_back(p);tr[p].push_back(i);
}dfs(1,0);dp[1]=1;int v;
for(i=1;i<=n;i++) if((v=(s[1]/gcd(s[i],s[1])))<=n) f[v]++;
for(i=n;i>=1;i--) for(j=i+i;j<=n;j+=i) f[j]+=f[i];
for(i=1;i<=n;i++) f[i]=(f[i]==i);
for(i=1;i<=n;i++){
if(!f[i]) continue;
for(j=i+i;j<=n;j+=i) (dp[j]+=dp[i])%=mod;(ans+=dp[i])%=mod;
}printf("%lld\n",ans);
return 0;
}
D-graph
大分讨。一下点的度数若无特殊说明均为模 以后的结果。
-
如果有入度为 的点那么只保留它即可。
-
如果有两个入度为 的点且他们的路径上只有入度为 的点那么就保留这两个点的路径上的点即可,可以证明如果图中有至少 个入度为 的点就一定会存在如上路径。
-
如果有仅由入度为 的点构成的环就保留这个环即可。
-
剩下的情况就是只有 个入度为 的点和一个由入度为 的点构成的森林。首先,这个入度为 的点必然存在,要不然叶子结点的度数不可能是 。其次,森林至少有 棵树。因为一棵树对度数为 的点的贡献为 。所以考虑找 颗树并分别保留 个叶子结点和路径以及这个入度为 的节点。
特判一下保留下来的点是整个图的情况。
Ex-math
分析
首先发现当取到 时,,所以有 。
另一方面,设 是一个满足条件的正整数,设 是所有满足原式的正整数对中使得 最小的一对。
若 ,则 。
若 ,不妨设 ,此时原式可以变形成关于 的一元二次方程
,设其另外一个实数解为 ,由韦达定理可知 ,又因为 ,即 ,所以 为正整数,此时, 也是满足原式的正整数对,因此
,于是有 ,且 ,于是有
,所以 。
本文作者:l_x_y
本文链接:https://www.cnblogs.com/lxy-2022/p/mo-ni-sai-ti-jie.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步