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{+}}\)
\(\color{green}{\texttt{+}}\):赛时通过 \(\color{red}{\texttt{+}}\):赛后通过 \(\color{gray}{\texttt{+}}\):未知 \(\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)\)

#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)\)

提交记录

posted @ 2021-10-25 18:58  Flying2018  阅读(64)  评论(0)    收藏  举报