AtCoder Regular Contest 068 ~ 072

C D E F
ARC068 $\color{gray}{\texttt{+}}$ $\color{gray}{\texttt{+}}$
ARC069 $\color{gray}{\texttt{+}}$ $\color{gray}{\texttt{+}}$
ARC070 $\color{green}{\texttt{+}}$
ARC071 $\color{green}{\texttt{+}}$ $\color{green}{\texttt{+}}$ $\color{green}{\texttt{+}}$ $\color{green}{\texttt{+}}$
ARC072 $\color{green}{\texttt{+}}$ $\color{green}{\texttt{+}}$ $\color{green}{\texttt{+1}}$ $\color{red}{\texttt{+}}$

AtCoder Regular Contest 068

E. Snuke Line

考虑最难办的事情其实就是每个车站内自己的去重。可以发现,对于 $d$ 的列车,如果某个区间长度 $\geq d$,那么其必然会被经过,否则其至多被经过一次。

所以直接处理按从小到大顺序枚举 $d$,对于长度大于当前 $d$ 的区间不用加入,复杂度 $O(n\log n)$。

提交记录

F. Solitaire

考虑加入存在完成后整个序列一定是 $\text{/}$ 形状的,考虑要让 $1$ 出现在第 $k$ 个位置,那么还会剩下 $n-k-1$ 个,可以发现无论如何剩下的一定是一段递增或是递减的序列。且其中的最大值小于同向部分弹出的最小值。

用 $f _ {i,j}$ 表示 前 $k-1$ 个数中,已确定了 $i$ 个数,最小值为 $j$。

考虑新加的数,有转移式 $f _ {i,j}\rightarrow f _ {i+1,j}\ ,\ f _ {i+1,k\leq j}$。

后者直接后缀和处理,复杂度 $O(n^2)$。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<iostream>
#include<cstdio>
#include<cstdlib>
#define ll long long
#define mod 1000000007
#define N 4010
using namespace std;
ll f[N][N],g[N][N];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
g[n+1][0]=1;
ll res=1;
for(int i=1;i<=n-k-1;i++) res=res*2%mod;
for(int i=n;i>=1;i--)
{
for(int j=0;j<=n;j++)
{
(g[i][j+1]+=f[i+1][j]+g[i+1][j])%=mod;
(f[i][j]+=f[i+1][j]+g[i+1][j])%=mod;
}
if(i!=1) for(int j=n;j>=0;j--) (f[i][j]+=f[i][j+1])%=mod;
}
printf("%lld\n",f[1][n-k]*res%mod);
return 0;
}

AtCoder Regular Contest 069

E. Frequency

考虑策略显然是用一条线从上往下压,同时压到的部分从后往前删。

直接维护此时最小的位置与要删的数量即可。复杂度 $O(n\log n)$。

提交记录

F. Flags

考虑二分答案,这样相当于若干条“选了 $x$ 就不能选 $y$”,直接跑不太行,直接线段树优化建图跑 2-sat 即可。

复杂度 $O(n\log^2 n)$。

提交记录

AtCoder Regular Contest 070

E. NarrowRectangles

容易发现若干 $|x-a_i|$ 构成的函数一定是凸的,考虑大力维护这个凸函数。

考虑用小根堆维护最小值右边的函数,大根堆维护左边,分别维护断点。

考虑每次加入一个元素后的影响:相当于在最优位置插入了一条斜率为 $0$ 的线段,然后比 $r$ 小的 $+1$,比 $r$ 大的 $-1$。

考虑每次至多 $+1$,所以至多把每个堆的一个元素扔到另一个堆里,所以复杂度是对的。

复杂度 $O(n\log n)$。

提交记录

AtCoder Regular Contest 071

E. TrBBnsformBBtion

首先直接把所有 $B$ 变成 $A$ 再消掉,一定可以得到 $\leq 2$ 个 $A$。

然后同样从 $\leq 2$ 个 $A$ 一定可以变成任何串。

所以令 $A=1,B=2$,两个串可以互相转化当且仅当两个串的和模 $3$ 相等。

提交记录

F. Infinite Sequence

考虑如果有超过两个非 $1$ 的位置,后面一定全部相等。

如果第一个填的是 $k,k>1$,并且后面不全相等,那么后面 $k$ 个必须是 $1$。

所以枚举第一个填什么,可以列出 dp 式子:

$$f_i=f_{i+1}+(n-1)^2+\sum_{k\geq 2}f_{i+k+1}$$

直接后缀和一下即可。复杂度 $O(n)$。

提交记录

AtCoder Regular Contest 072

D. Alice&Brown

打个表发现答案是 $|X-Y|\leq 1$。考虑证明:

  • 首先 $(0,0),(1,1),(0,1),(1,0)$ 显然先手必败。
  • 对于 $|X-Y|>1$ 不妨假设 $X>Y$,这样从 $X$ 中取 $\lceil\frac{X-Y}{3}\rceil$ 就会变成 $|X-Y|\leq 1$。
  • 对于 $|X-Y|\leq 1$ 显然不存在构造。

E. Alice in linear land

设修改的位置是 $p$。首先 $1\sim p$ 部分处理的结果是固定的,对于修改来说,显然此时距离原点越远越好。

从后往前我们尝试构造 $f_i$ 表示从 $i$ 开始最小的距离满足不能到达。容易发现如果我们知道了 $f_{i+1}$,对于 $a_i$ 我们只要考虑会不会影响到达,如果不会就直接取上一个值,否则我们构造 $f_{i+1}+a_i$。

最后只要判断这两个值哪个大即可。

提交记录

F. Dam

首先显然只要让总热量最大,除以 $L$ 就是答案。

设 $f_i(x)$ 表示第 $i$ 次加水后,剩余水量为 $x$ 的最大热量,容易发现此时不断放水就可以取到原点线段上的点,所以这个函数一定是上凸的。

尝试维护这个凸包。可以发现当冲入 $(x,y)$ 的水后,等同于在前面加上了 $(x,y)$ 这个向量。如果此时队首向量斜率大于当前向量,换句话说我们不会主动放掉队首对应的水,那么就直接混合这两部分即可。

最后我们只需要截取 $f(L)$ 即可,可以发现超过 $L$ 的可以直接扔掉,所以用一个双端队列即可。

复杂度 $O(n)$。

提交记录