zoukankan      html  css  js  c++  java
  • atcoder做题记录

    AGC040A ><

    冷静思考可以发现每个位置可以填的最小值是左侧连续小于号的个数和右侧连续大于号的个数的较大值。扫一遍即可。

    AGC040B Two Contests

    对于两个区间(A,B) ,假设(A) 包含(B) ,那么(A) 一定和(B) 被分在一个组中,因为(A) 放在(B) 所在的组中不会影响该组的答案,而放到另一组中可能会减小答案。因此可以忽略所有这样的(A) ,将剩下区间按左端点排序,那么右端点也一定有序。此时最优方案一定是一个前缀+一个后缀。预处理后缀左端点max和右端点min,枚举分界点即可快速得到答案。注意有特殊情况,即某个区间单独成一组。

    对于区间问题从两个相包含的区间入手是一种很不错的方式。

    AGC040C Neither AB nor BA

    考虑将序列编号为奇数的染黑,其他的染白。那么每次操作必然是一黑一白两个位置。我们将黑色位置的A变为BB变为A,此时题意可以转化为除了AA,BB两种子串外其他长度为2的均可删除。容易发现不满足要求的串当且仅当A/B的总出现次数超过(frac n2) ,因此直接容斥计数即可。

    积累下本题的特殊做法。

    AGC040D Balance Beam

    对于一种已经确定的排列顺序,必然存在一个分界点使得Bob在分界点左侧出发一定被抓住,在其右侧出发一定不会被抓。

    为了使得这个问题更加形象化,我们考虑建立纵坐标代表时间,横坐标代表位移的图像,那么Alice和Bob的图像就是一个从((0,0)) 出发,分别到达((n,s_a),(n,s_b)) 的分为(n) 段的折线((s_a=sum_{i=1}^na_i,s_b=sum_{i=1}^nb_i)),而Alice会抓住Bob当且仅当两条折线存在交点。现在,我们将Bob的折线向下平移至即将和Alice的折线没有交点(但是仍然有交点)的位置,此时设折线和(x) 轴的交点为((k,0)) ,我们现在需要最大化(k)

    对于一条从((k,0)) 出发,先沿着Bob的折线走,然后再沿着Alice的折线走的折线,其终点一定是((n,s_a)) 。我们假设((k,0)) 所在的石块为(p) ,需要尽可能地最大化折线的增长速度就能得到最大的(k) 。观察可以发现第(i) 段的斜率最大为(max (a_i,b_i)) ,因此我们可以将石块按照(max (a_i,b_i)) 从小到大进行排序,二分找到最大的(t) 满足(t) 处的(max (a_i,b_i)) 后缀和不小于(s_a-b_p) 。(为什么一定可以取到最大?其实只需要先放(b_i>a_i) 的石块,然后再放(a_i>b_i) 的石块即可。)至于此时(k) 的具体值可以通过简单的计算得出。然后枚举(1sim n) 作为(p) ,不断取(max) 即可。

    本题启示我们当问题过于繁琐时可以通过画图来使问题具象化,方便思考。

    AGC040E Prefix Suffix Addition

    题中所述的两种操作事实上可以看做对任意一个区间加上一个单调不降/不增的序列,因为我们可以在前面添加0。

    然后可以发现对于其中一种操作,通过调整一定可以使得覆盖的范围互不相交,因为对于相交的部分我们可以直接叠加到一个操作上,由于不降序列+不降序列仍然不降,因此这样一定满足条件。

    (b_i,c_i) 分别表示1操作和2操作对位置(i) 的贡献((b_i,c_ige 0))。显然必须满足(b_i+c_i=a_i) 。我们需要将(b,c) 划分为尽量少的单调不降/不增连续段。强制钦定(a_0=a_{n+1}=0) ,那么在(b_i,c_i) 都确定后的答案就是(sum_{i=0}^n([b_i>b_{i+1}]+[c_i<c_{i+1}])) 。最小化这个东西即可。

    考虑dp。令(f_{i,j}) 表示考虑前(i) 个位置且(b_i=j) 时的贡献。那么有转移:

    [f_{i,j}=min_k(f_{i-1,k}+[k>j]+[a_{i-1}-k<a_i-j])\ Rightarrow f_{i,j}=min_k(f_{i-1,k}+[j<k]+[j<a_i-a_{i-1}+k]) ]

    根据转移方程容易发现当(i) 不变时,(f_{i,j}) 随着(j) 不增。同时一定有(f_{i,0}le f_{i,a_i}+2) 。因此我们只需要维护(f_{i,x}=k)(x) 的范围,由于不同的(x) 最多3种,因此直接转移即可。复杂度(mathcal O(n)) 。具体实现时二分会更好写,不过复杂度会多个$log $ 。

    AGC040F Two Pieces

    我们考虑用二元组((x,d)) 表示两个点的位置信息,其中(x) 表示靠前的点的位置,(d) 表示两个棋子之间的距离。那么对应于原操作,有以下三种操作:

    • ((x,d)leftarrow (x+1,d+1))
    • ((x,d)leftarrow (x,d-1)(dge 2))
    • ((x,d)leftarrow (x,0))

    注意第二种情况必须保证(dge 2) ,这是因为如果(d=1) 时执行2操作效果会和3操作相同,而这样处理后我们便不再需要对于位置计数,而只需要对于操作序列计数了。

    最终到达的状态为((B,B-A)) 。容易发现1操作必须恰好进行(B) 次。而后我们可以枚举2操作的次数为(k) ,还剩下(N-B-k) 次操作3。在只考虑1,2两种操作情况下,我们需要时刻保证(dge 1) (初始时刻除外)。这种情况下的方案数可以用类似求卡特兰数的方法求出方案数,结果为(dbinom {B+k-1}k-dbinom{B+k-1}B)

    现在我们只需要将(N-B-k) 次3操作插入这个操作序列即可。考虑到在(i) 处进行一次3操作,那么(forall tin[i,B+k] d_tleftarrow d_t-d_i) 。因为我们要保证(d_tge 1) ,因此(forall tin[i,B+k] d_t>d_i) ,即能插在(i) 操作后当且仅当不存在(j>i) 使得(d_jle d_i) 。而观察到(d) 每次的变化量只有1,因此对于(d_t=x)(x) 为某定值)的所有(t) ,我们只能在最大的(t) 处插入若干3操作。现在我们的状态是((B,B-k)) ,需要将它变为((B,B-A)) 。假设我们在(c_1,c_2,cdots ,c_p) 这些位置进行3操作,那么最终状态的变化为(max_i d_{c_i}) ,因此(max_i d_{c_i}=(B-k)-(B-A)=A-k) ,这意味着我们需要在(d_t=A-k) 的最大的(t) 处进行至少一次操作。不妨设(N-B-k>0)(N-B-k=0) 的情况是trivial的,合法当且仅当(k=A) ),还剩下(N-B-k-1) 次操作可以任意地放入(d_t=0sim A-k) 的最大的(t) 处,即将(N-B-k-1) 个球放入(A-k+1) 个盒子的方案数,为(dbinom {N+A-B-2k-1}{A-k})

    将两部分方案乘起来,枚举(k) 求和即可。复杂度(mathcal O(n))

    NO PAIN NO GAIN
  • 相关阅读:
    Linux.Unix.windows的纠结史
    第一次来到博客园
    canvas的fillText参数解释
    【转】Javascript画立体玫瑰
    C#学习笔记(有C,C++,JAVA语言基础)
    推荐NHibernate新书:NHibernate 3.0 CookBook[附下载]
    NHibernate之旅系列文章导航
    存储过程
    .Net下的 ORM框架介紹
    十步让你成为更优秀的程序员
  • 原文地址:https://www.cnblogs.com/zmyzmy/p/15477814.html
Copyright © 2011-2022 走看看