冷滟泽的个人博客冷滟泽的个人博客

CF933 总结

A. A Twisty Movement

若是给定一个 1/2 序列求它的最长不降子序列,可以枚举一个分界 i ,使 i 左边的 1 + i 右边的 2 最大。

如果是翻转一个区间的话,这个分界一定会取在翻转的区间内,否则就不如不翻转。

我们依然枚举 i ,并找出一个覆盖 i 的区间 [l,r] 翻转。其中 [l,i] 的贡献为它内部 2 的个数 - 1 的个数;[i+1,r] 的贡献为它内部 1 的个数 - 2 的个数。两边暴力找出最优的端点即可,也可以递推做到 O(n)

这道题让我想到了 HDU6357 。那题的数据范围和值域都要比这题大,做法也不同。这里是我的题解作为参考。

B. A Determined Cleanup

考虑多项式 f(x)x+k 的结果是什么。模拟厂除法的过程,得出

p=f(x)\mod{x+k}=-k\left(-k\left(-k\left(-ka_{d-1}+a_{d-2}\right)+a_{d-3}\right)+...\right)+a_0

发现第 i 位恰好被 -k 贡献了 i 次,因此有

p=\sum_{i=0}^{d-1}(-k)^ia_i

可以看出 \{a_i\} 就是 p-k 进制下的表示。于是直接短除法转换进制即可。

C. A Colourful Prospect

虽然可以讨论,但这里考虑 n 平凡的情况。

考虑欧拉公式:V-E+F=2V,E,F 分别表示平面图的点数、边数、面数。这个图可能有多个连通块,设连通块数为 C ,则有 Ans=E-V+C+1。大力枚举两个圆,算它们的交点并去重即可算出边数和点数。至于连通块的个数,当然可以并查集求,但这题只有 3 个圆,可以统计与其它圆没有交点的圆的个数。

下面是核心代码,省略了计算几何模板:

int ans=2; bool flag=1;
PointSet ps;
for (int i=0; i<n; i++)
{
    PointSet inter;
    for (int j=0; j<n; j++)
        if (j!=i) getCircleIntersection(c[i], c[j], inter);
    eraseCoincideElements(inter);
    ans+=inter.size()+inter.empty();
    if (!inter.empty()) flag=0;
    for (Point P:inter) ps.push_back(P);
}
eraseCoincideElements(ps);
ans-=ps.size()+flag;
printf("%d\n", ans);
未经允许不得转载:冷滟泽的个人博客 » CF933 总结

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址