一天一场ARC有利于身心健康?
ARC066C Addition and Subtraction Hard
首先要发现两个性质:
加号右边不会有括号:显然,有括号也可以被删去,答案不变。
(op_i)和(A_{i+1})之间只会有一个括号:有多个括号的话只保留最外边那个,答案不变。
然后就可以定义状态:(dp_{i,j})表示前(i)个数,还有(j)个未闭合的左括号,得到的最大答案。
由于只有减号右边有括号,所以只要知道左边有几个未闭合的左括号,就可以知道自己的贡献是(1)还是(-1),所以转移也很容易了。
然而状态是(O(n^2))的,不怎么行。
然而还可以发现一个性质:嵌套的括号不超过两层。超过两层的可以通过调整顺序消去一多余的。
那么就做完了。
AGC033C Removing Coins
首先可以发现,每次操作就相当于两种选择:要么删掉所有叶子,要么留下一个叶子删掉剩下的。
然后再可以发现:每次操作可以选择把树的直径减少(1)或(2)。
那么求出树的直径之后就变成了一个简单的取石子游戏了。
AGC014D Black and White Tree
从叶子开始考虑。如果白点点了叶子的父亲,那么黑点就必须点掉这个叶子,然后这两个点就对后面没有影响了,可以删掉。
冷静思考一番,发现只要一直这样删删删,看最后有没有点剩下来就好了。
ARC063F Snuke's Coloring 2
为了方便,假设四周都有一些点。
问题显然可以转化为:求周长最大且内部没有点的矩形。
首先注意到一点:答案至少为(2(max(W,H)+1))。
根据这一点,可以得到一个性质:矩形至少过(x=lfloor W/2rfloor)和(y=lfloor H/2rfloor) 中的一条直线。
如果两条直线都不经过,那么就算一个点都没有,也不会达到下界。
既然两种情况那么像,接下来只考虑过(x=lfloor W/2rfloor)的情况。
考虑枚举上边界(y_r)、下边界(y_l),设(x_l=max{x_i|y_iin[y_l,y_r],x_ile lfloor W/2rfloor}),(x_r=min{x_i|y_iin[y_l,y_r],x_ige lfloor W/2rfloor})。
那么答案就是(2(y_r-y_l+x_r-x_l))。
考虑优化,只从下往上枚举(y_r),用单调栈+线段树动态维护每个(y_l)的答案,复杂度(O(nlog n))。
ARC068F Solitaire
考虑一个合法的双端队列是什么样子——肯定是形如(P_11P_2),其中(P_1)为单调下降序列,(P_2)为单调上升序列。(形象一点就是一个V)
既然第(K)个必须是1,那么前(K-1)个数必须能拆成两个可以为空的单调下降序列,而且后面(n-K)个数小于两个序列的结尾的最大值。
于是可以开始DP:设(dp_{i,j})表示前(i)个数,较小的结尾的数是(j),的方案数。
考虑下一个接的数(k)与(j)的大小关系:
- (j>k,dp_{i,j}rightarrow dp_{i+1,k})。
- (k>j),注意此时(k)只能放没有出现过的数的最大值,其它都是不合法的,所以有(dp_{i,j}rightarrow dp_{i,j+1})。
第一个转移用前缀和优化一下。
统计答案时考虑没有出现过的(n-K)个数有(2^{max(0,n-K-1)})种放法,乘上去即可。
ARC078F Mole and Abandoned Mine
删掉的边权值最小转化为保留的最多。显然,最后剩下的图一定时连通的。
那么可以得到一个性质:从(1)到(n)上的路径的每一条边都是桥,连接两个连通块。如果把路径上的边删掉,那么这些连通块之间没有边,每一个连通块也只和路径上一个点连通。
于是可以开始DP:设(dp_{S,x})表示当前与(1)连通的点集是(S),路径末端的点是(x),的方案数。
转移有两种:往(x)点连上一个连通块(T)并把(T)中的边都连上,或是从(x)往(y)连一条边并把终点置为(y)。
AGC001F Wide Swap
首先转化一下:设(q_{p_i}=i),那么变为每次在(|q_i-q_{i+1}|ge K)时可以交换(q_i,q_{i+1}),最后要使得(1,2,cdots)在(q)中出现的位置尽量靠左。
那么可以发现,若(|q_i-q_j|<K),那么(q_i)与(q_j)的位置关系永远不变。
放回到(p)中,就是如果(|i-j|<K),那么(p_i)和(p_j)的大小关系永远不变。
也就是说,若(p_i<p_j),那么就一定有(p'_i<p'_j)。
那么可以建出一个图:若(p_i<p_j,|i-j|<K),那么连一条(irightarrow j)的边,表示(p'_i<p'_j)。
然后给每一个点编号,要求字典序最小。
这个问题有一个这样的解法:设当前出度为0且编号最大的点为(x),那么把(x)标号为(n),然后删去(x),--n。
为什么是对的?若(x)标为(w),那么把(x)变为(n),把原标号为([w+1,n])的点的标号都减一,显然更优。
然后怎么实现它呢?
发现每次需要找最右边的(i),使得对于(jin (i-K,i+K))且(j)没被删,都有(p_j<p_i)。
把原数列每(K)个分一组,那么位置(i)可以被选必须有(p_i)是自己组的最大值。
那么其实每组每次最多只会有一个位置可选,而删掉一个位置之后也只需要更新旁边三组的位置。
线段树随便搞搞就好了。
AGC003D Anticube
考虑相乘起来为(x^3le 10^{20}),那么(xle 10^{10/3}),(x)中最多只有一个(ge10^{5/3})的质因数,(x^3)中最多有三个。
所以(s)中不会有(ge 10^5)的质因数,否则可以直接被加入答案。
把([1,10^{10/3}])的质数筛出来,设(s=prod p_i^{w_i},a_i=w_i%3,s'=prod p_i^{a_i}),那么接下来可以只考虑(s')。
求(s')的方法:若(s)除掉([1,10^{10/3}])的质数之后不为1,那么可以简单判一下是不是((10^{10/3},10^5])的质数(或平方)。
把(s')求出来之后,每个数能与它组成三次方数的数是惟一的,可以简单地选取更大的那个子集。
AGC003E Sequential operations on Sequence
首先,显然可以用一个单调栈把(q)变成单调上升的序列。
然后,注意到每次操作就是把原序列复制几遍,再接上一个前缀。
那么可以dp:记(f_i)表示第(i)次操作之后的序列在最终序列中出现的次数。
每一次可以转移:(f_i=f_{i+1}times lfloor q_{i+1}/q_irfloor)。
但是那个前缀怎么办?
前缀并不会计入(f_i),但会被算进(f_j(j<i)),所以往前面递归,看它们出现了多少次。
注意到每次前缀长度会对(q_j)取模,而(q_jle len)时(len)至少变小一半,所以只会变化(log len)次,可以二分出下一次变化的地方。
最后递归到第一次还有剩余时就直接加入答案即可。
AGC004C AND Grid
构造题……
发现周边格子不会有紫色,这很有趣。
于是就有了这样一个构造方法:上面红,下面蓝,奇数列红,偶数列蓝。
显然这是满足条件的,可是又是怎么想出来的呢??
AGC004E Salvage Robots
注意到机器人动其实等价于出口和边界在动。
注意到出口一旦动,那么它动的整个矩形里还没有自爆的机器人都会被救。
也就是说,若出口向右4格向上2格,那么这个(2times 4)的矩形里的机器人都会被救。
于是DP:记(f_{l,r,u,d})表示出口走了((l,r,u,d)),最多被救多少个。
注意走了((l,r,u,d))时整个大矩形的左边(r)列肯定已经没有机器人了,(l,u,d)同理,转移时要注意。
AGC004F Namori
神仙模型转化……
树
注意到树是一个二分图,那么可以先黑白染色一下。
然后做一个奇特的转化:把奇数层的点的颜色反转一下,那么每次操作就变成了交换相邻颜色不同的点的颜色,目标是反转每个点的颜色。
记黑点权值为(1),白点权值为(-1),那么总权值必须为(0),否则无解。
再神奇地转化一下:黑点上有个球,白点上有个洞,每次可以把一个球滚进去相邻的一个空的洞里,最后每个洞里都要有一个球。
考虑每条边被滚过的次数,就是子树中球和洞的个数差,所以答案就是
[ sum_x|sum_x| ]
奇环
任意删掉环上一条边,现在相当于这条边的两个端点可以同时出现或消失球。
那么如果(sum_1ne 0)就无解,否则增加的球数是固定的,直接算即可。
偶环
任意删掉环上一条边,现在相当于这条边的两个端点可以一边出现球,另一边消失等量的球。
那么显然(sum_1ne 0)时无解,否则设这条边为((u,v),dep_u<dep_v),(v)点出现(k)个球(或消失(-k)个球),那么((u,v))这条链的贡献就变为了
[ sum_u+sum_{xin(u,v),xne u} |sum_x+k| ]
这就是个数轴上使总距离最小的题,取中位数即可。
AGC005E Sugigma: The Showdown
如果想到怎么判-1那么就很好做,但谁会直接想什么时候-1呢?
考虑红树上的每一条边((u,v)),如果蓝树上(dis(u,v)>2)((dis(u,v))指两点之间的边数),而且sigma可以比sugim先到某个端点,那么sigma就可以在这条边上跳来跳去,而sugim永远也抓不到。
如果没有这样的边,在蓝树上以sugim的出发点为根,那么sigma只能往父亲、父亲的父亲、子树内、兄弟这几个地方跳,sugim步步为营,总能抓到的。
那么他到底能存活多久呢?按照贪心的策略,当然是在不被抓到的情况下跑到蓝树上深度最深的点,然后乖乖等死。这个可以一个bfs搞定。
AGC005F Many Easy Problems
这题还真不怎么像AGC的题。
考虑点(x)对(f_k)的贡献:没有贡献时要么是全都在祖先那里,要么是全都在某个儿子的子树里,所以贡献是
[ {nchoose k}-{n-size_xchoose k}-sum_v {size_vchoose k} ]
把所有贡献加起来,就是
[ n{nchoose k}-sum_{x=2}^n left( {size_xchoose k}+{n-size_xchoose k} right) ]
把(size)和(n-size)放到桶里,那么答案就是
[ n{nchoose k}-frac 1 {k!} sum_{i=1}^n cnt_ii!times frac 1 {(i-k)!} ]
显然是个卷积,NTT一下即可。
AGC006C Rabbit Exercise
见过的套路题……但还是没做出来……
如果本来是(x_{i-1},x_i,x_{i+1}),然后搞了(x),那么(x_i)的期望就会变成(x_{i+1}+x_{i-1}-x_i)。
然后发现似乎可以直接把期望丢回去,就当做(x_i)变成了(x_{i+1}+x_{i-1}-x_i)。
然后……
然后差分一下,发现一次操作就是交换相邻两项,然后记录一组操作之后会发生什么,然后倍增。
AGC006D Median Pyramid Hard
容易想到二分答案,然后底下转化为01串。
手造数据找规律,发现离中心最近的连续两个相同格子的数就是答案。
也有可能没有连续的,特判一下即可。
AGC006E Rotate 3x3
容易发现一列肯定一起动,而且只有递增/递减两种情况。
定义交换表示换位置,翻转表示换状态。
容易发现奇列怎么换都不会换到偶列。
手玩之后发现可以同时翻转相邻的奇列/偶列。
发现一次操作后有一组位移、三个翻转,而三个翻转其实可以变成一个。
更精确地讲,交换相邻奇列的唯一副作用就是翻转中间的偶列。
全都归位之后又可以同时翻转两列。
总的来说,就是奇列的交换次数要与偶列的交换次数同奇偶、偶列的交换次数要与奇列的交换次数同奇偶。
AGC006F Blackout
神仙题……
考虑到棋盘太大,也不好想象,就把它转成图。
现在:如果有边((x,y),(y,z)),那么连上((z,x))。
脑抽想到三染色:对于每个弱连通分量(有向看作无向),规定如果有边((x,y)),那么$col_y=(col_x+1)text{ mod } 3 $,然后会有三种情况:
第一种:有两种颜色且存在合法方案——容易发现这样一条新边都连不了。
第二种:有三种颜色且存在合法方案——可以发现此时所有((0,1),(1,2),(2,0))的边都能连了。
第三种:无合法方案——可以发现此时所有边都能连上,包括自环。
于是dfs一下就做完了。
AGC007C Pushing Balls
又是一道神仙题,做不来qwq
首先把题目抽象成(2n+1)个端点,每次等概率删除两个相邻端点,并加上他们的距离。
发现题目给的等差数列这个条件特别奇怪,于是可以列几个小数据来看做完一次操作后第(i)个区间的期望长度。(这里的第(i)个是重新编号的)
然后发现它竟然还是个等差数列!!
然后就假装每次都还是等差数列,继续做就好了。
AGC007E Shik and Travel
显然进了一棵子树就要把这棵子树的叶子走完再上去。
我们先二分答案,然后状态可以被抽象成二元组((a,b)),表示从这里下去还要再走(a)的距离,上来要走(b)的距离。在每个点把可用状态全都存下来,注意如果(ale a',ble b')那么((a',b'))就废了。
在非叶子节点合并的时候可以发现对于((a,b)),要选一个(a')尽量大的方案与它合并,所以直接二分+启发式合并就好了。
AGC007F Shik and Copying String
首先从右往左贪心的思路非常显然,但这个思路比较模糊,我们需要把它抽象成数学模型。
我们可以把向右覆盖的操作看作向右的水平线段,而继承到下一个版本的操作看作竖直线段,那么每个字母都可以被看作是一段折线,我们就是要在折线互不相交的情况下使时间最少。
画画图可以发现,折线的转折点会贴着上一条折线走,即在上一个转折的基础上向左向下一格。
于是可以维护一个队列来判断当前折线会走到上一条的哪个转折后停下,也就可以算出答案了。
感觉很难讲得明白,贴个代码:
int ans=0,pos=n;
drep(i,n,1)
{
if (t[i]==t[i-1]) continue;
chkmin(pos,i);
int cur=i;while (t[cur+1]==t[i]) ++cur;
while (l<=r)
{
int x=q[l]-(r-l);
if (cur>=x) break;
++l;
}
while (pos&&s[pos]!=t[i]) --pos;
if (!pos) return puts("-1"),0;
q[++r]=pos;
chkmax(ans,r-l+1);
}
AGC008C Tetromino Tiling
首先通过手玩,可以发现只有1245可以用,而2可以单独考虑,所以只用管145。
145只有几种玩法:1+4+5,1+1,4+4,5+5。
于是随便判一下即可。
AGC008D K-th K
直接按顺序贪心地放次数还不够的数,没得放了就放已经完成的数。
AGC008E Next or Nextnext
建图,对于某个合法方案(p),连(irightarrow p_i),那么一定可以组成若干个环。
再连(irightarrow a_i),那么这条边在环上一定只有两种情况:和原来的边一样,或是跳过了一个点,到了下一个点。
如果所有边都一样,那么显然还是原来那个环。
如果所有边都跳了一下,那么如果环是奇环就还是一个环,否则就会分裂成两个环。
如果有些跳有些不跳,那么就变成了一棵特殊的基环树,这里的“树”其实是一条链。
现在我们手上有(irightarrow a_i)的图,考虑如何复原出(irightarrow p_i)的图。
对于长度相等的简单环可以一起考虑,分自己成一个环和与前面环合并来讨论。
对于基环树,要把那些多出来的链塞回去。由于我懒得画图,所以比较难讲明白,可以去看这里。(Orz litble)
AGC008F Black Radius
这题的难点其实就是枚举的时候要做到不重复,所以我们先把每一个合法连通块与另外一种表示方法唯一对应起来。记这个连通块的直径的中点为(x)((x)也可以是一条边),半径为(d),那么二元组((x,d))就唯一表示了一个合法连通块。(画画图感受一下可以证,不过感觉这种题都是要先猜结论再慢慢证的)
现在我们的任务:枚举(x),算出有多少个(d)是合法的。
如果(x)是连接(u,v)的边,且(mxdep_ule mxdep_v),那么显然我们要填满子树(u),然后再延伸到(v),否则(x)就不会是中心。于是当(u)子树内有好点的时候它对答案有1的贡献。
否则,感性理解一下,合法的(d)一定组成了一个区间。我们分两种情况讨论。
1. (x)是好点。此时显然下界为0。设以(x)为根的时候(x)的儿子分别为(u_1,u_2,cdots),那么上界就是(mxdep_u)的次大值。
2.(x)不是好点。此时可以发现上界没有变化,而下界则成为了(min{mxdep_u|vin tree_u,v is good })。
于是(O(n))的树形DP做一遍即可。
(通过上面的分析其实也证明了(d)组成了一个区间)
AGC009D Uninity
首先要做一个转化:以(v)为中心点合并一些权值为(k)的树的时候,把(v)的权值赋为(k+1),于是题目就转化为求一种编号方法,使得任意两个权值为(k)的点之间有权值更大的点,最小化最大权值。
(证明:任意一种原方案显然可以转化为一种合法的编号方案,而一种合法的编号方案可以每次提出权值最大的点,转化为合法原方案)
发现可以贪心。对于每棵子树,记录哪些权值到根的路径上没有更大的权值(记为“出现”)。合并子树的时候看一下同时有两个出现的最大权值(k)是多少,然后自己就取(k+1),把([0,k])都记为未出现。(本质就是取能被取的最小权值,因为取更大的权值显然没有益处)
根据点分治的思想,最大权值肯定不会超过(log n),所以可以直接开数组。
AGC009E Eternal Average
首先还是要做一个转化: 把求平均值的操作看做一棵(k)叉树,0/1都在叶子上,非叶子节点的权值是(k)个儿子的平均数。
考虑每个1对根节点的贡献,其实就是(k^{-dep_x})。
这个分数如此的不友善,所以我们要把它变得好看一点。把最后的结果写成(k)进制,那么就会变成
[ 0.s_1s_2s_3s_4s_5cdots s_l ]
这个式子必须满足一些条件:
[ sum s=mpmod{k-1}\ 1+ltimes (k-1)-sum sle n ]
(条件的意思:1. 考虑进位之后,各位数字之和要与(m)同余;2. (n)个0要足够把它补成一棵完全二叉树)
然后就可以DP:设(dp_{i,j})表示小数点前(i)位,数位和为(j),的方案数。前缀和优化一下即可。
AGC010C Cleaning
经典题,但就是没做过,所以自闭了。
可以发现点权确定之后就可以确定每条边的边权:对于叶子节点,他的点权等于连向父亲的边权;对于非叶子节点,他的点权等于周围边权之和。容易发现只要这样一路推上去即可得到每条边的边权。
如何凑出方案呢?容易发现,只需要这个点旁边的边权的最大值不超过总和的一半,那么就一定可以相互抵消成0,所以一定有解。
所以dfs一次就完事了。
AGC010D Decrementing
博弈论怎么可能做得出来呢……
首先要发现,当局面有奇有偶的时候,除以(gcd)操作必然不改变奇偶性。
注意到一个关键性质:结束局面必然全是1,也就是没有偶数。于是可以推出:当当前局面没有偶数的时候,你只能变出一个偶数来,而对手一定又可以变回去,直到你输掉。所以,全奇数的局面是必败的。
有偶数呢?我们对偶数个数的奇偶性分类讨论。
奇数个偶数时,你操作一个偶数变为奇数,对方不管如何处理,偶数个数的奇偶性不变。最后总能到达你操作完之后全是奇数的必败态。所以,偶数个数为奇数的时候必胜。
偶数个偶数时,显然操作偶数之后会到达必胜态,所以要操作奇数。如果不止一个奇数那么肯定也输了,而只有一个奇数的话就会所有数除以2,事情可能会发生转机,所以要递归处理。
显然递归层数不超过(log a_i),所以可以直接暴力。
AGC010E Rearranging
我已经摸到AGC的套路了:一旦不会做就乱连个边,乱建个图,然后就对了。
(手动狗头保命)
可以发现,定下初始序列之后,不互质的数的相对顺序不会改变。
我们把不互质的数连起边来,成为若干个连通块,现在单独考虑每个连通块。
如果要最小化每个连通块的顺序的字典序怎么做呢?显然第一个可以放最小的,但这也就限制了第二个必须与第一个有边相连,同时也限制了后面的……但是没有关系,只要每次选与自己有边的、编号最小的往后dfs即可。
假设我们固定了每个连通块的顺序呢?可以发现后手一定会贪心地每次取最大的往前填,所以只要最小化每个连通块字典序即可。
AGC010F Tree Game
怎么这题反而比前面的题更简单……怎么我还是做不出来……
首先为了方便,每次判断一个点是否合法的时候就直接把他提到根,然后来判断每个点是否为必胜态。
对于(u),如果有一个儿子(v)满足(a_u>a_v),那么显然在(u,v)之间反复横跳是先手赢的,所以后手只能往(v)的儿子走,所以可以只考虑(v)的子树,递归处理。如果先手往(u)的父亲走呢?那么这一定说明先手已经不能往儿子走了,而原来的后手又为什么从(u)的父亲走到了(u)呢?这一定说明(a_{fa_u}>a_u),所以后手只需要逼得先手在(fa_u,u)左右横跳就可以稳操胜券,所以先手必然不会往上走。
所以枚举答案,(O(n))判断,就做完了。
ARC070E NarrowRectangles
一开始想了个假贪心,把自己叉掉之后就可以开始想DP了。
容易想到,设(dp_{i,j})表示前(i)段已经联通,最后那个的左端点的坐标是(j),的最小代价。随手画画图,可以发现他一定关于(j)是一个分段函数,而且是一个凸包,而且斜率在([-i,i])里,而且是连续的整数。于是只需维护每个分段点在哪里就可以知道凸包的形式。
转移的时候,发现一定是把中间一段推平,而两边由平移而来,最后加上一个绝对值函数。我们只需要每次转移的时候把最低点的纵坐标加进答案里,然后假装最低点在(x)轴上。
分类讨论:如果加上的函数的0点在被推平的区间里,那么新顶点显然。否则,如果在左边,那么新的最小值就在原来斜率(-2,-1,0)的分界点中间。如果在右边则同理。
所以直接搞两个优先队列维护左右分界点即可。
ARC070F HonestOrUnkind
首先想一下如何判无解。
可以发现,当假人数量大于等于真人的时候,可以有一部分假人伪装成真人,所以肯定无法知道谁是真人,此时无解。
然后就是各种脑洞做法,这里只讲其中一种好懂的。
发现一个性质:如果(x)说(y)假假,那么(x,y)必然不会全是真人。
于是可以发现:如果删掉(x,y),那么真人数量一定还是大于假人。
所以可以维护一个栈,栈里面(a_i)说(a_{i+1})是真人。
当加入当前这个人的时候,如果栈顶说他是真人,就把他加进去,否则就直接把这个人和栈顶都删掉。
最后考虑栈内的情况。由于有真人比假人多的限制,不可能全是假人。而显然又不可能出现某个真人前面是假人的情况,否则栈顶必然是真人。
AGC036F Square Constraints
我们以(i)为横坐标,(p_i)为纵坐标,发现满足条件的点在四分之一个圆环内。记([l_i,r_i])表示(p_i)所在的区间。
观察这个圆环,发现如果没有(xin [0,n])的点的(y)的限制,那么就是一个这样的问题:给定(r_i),求排列的个数。
这个问题很好解决:把(r)排序,然后答案就是(prod_i (r_i-i))。
但是有限制呢?考虑容斥,用(le r)的减去(<l)的。
然而这样可能就会对排名产生一些影响,从而不太好统计答案。
发现(l_ine 0)的(r)必然大于(l_i=0)的(r),而且(l_ine 0)的时候(r)随着(l)增大而增大。
于是可以枚举有几个位置选了(<l)的,然后就可以每次插入一个点的时候求出它的排名了。
不知道为什么细节就是很多……
ARC071E TrBBnsformBBtion
注意到经过操作可以使ab变成ba,于是顺序不重要了。
注意到aa和b可以互相转换,于是可以把两个串都变成只有a的形式,答案不变。
注意到如果原来长度模3余数不同,那么乘2之后也不会相同,所以直接判长度模3是否相同即可。
ARC071F Infinite Sequence
显然数列会是11121113111111151111112112222...这样,只是最后边界会有一些细节。
设(dp_n)表示长度为(n),最后给够了1,的方案数,那么就有(dp_n=sum_{i=0}^{n-1} dp_i-dp_{n-2})。
统计答案的时候分类讨论:最后是1且给够了;最后是1且没给够;最后不是1。
ARC072D Alice&Brown
打表找规律,发现(|x-y|le 1)的时候先手输,否则先手赢。
证明什么的归纳一下就好了,就是不知道如果不打表怎么想出来……
ARC072E Alice in linear land
推错了一个地方,离正解就差一点点……
处理出用前(i)个会走到距离(dis),然后发现改变之后距离可以是([0,dis])中的任意一个。
所以我们就要处理出每个后缀可以搞出的从0开始的距离区间。
发现只要有一个搞不出来,那么后面的都废了。
于是随便递推一下,就做完了。
ARC072F Dam
神仙题?
首先可以把水看做二元组((V,Vtimes t)),那么混合的时候可以直接相加。
维护一个水的单调队列,里面温度单调上升。
新加一些水的时候,如果水坝满了,那么显然放掉最前面的更优。
然后如果当前水比队尾的水温度低,那么如果后面要放水,肯定是要先混合再放水,所以一直往前混合直到当前水比队尾水温度高,这样也满足了单调性。
ARC073E Ball Coloring
看错题,做得我一脸懵逼?
考虑最大值和最小值是否在一个集合。
如果最大值为红,最小值为蓝,那么直接所有较大的设为红较小的设为蓝即可。
如果最大最小值都为红,那么把剩下的集合按较大的元素排序,枚举蓝色集合的最大值,搞一搞答案。
(我看不懂网上题解,又懒得写代码,所以这个可能是错的,但我觉得这题乱搞就完事了)
ARC073F Many Moves
做了不知道多少遍的套路题……
设(dp_{i,j})表示昨晚前(i)个,一个在(a_i)处,另一个在(j)处,的最小值,暴力转移是(O(qn))的。
发现可以线段树优化一下,没了。
ARC074E RGB Sequence
设(dp_{i,j,k,0/1/2})表示做完了前(i)个,第(i)个的颜色是红/绿/蓝,另外两种颜色最后出现的位置是(j,k)的方案数,每次在右端点处处理不合法的情况,直接删掉就好了。
ARC074F Lotus Leaves
容易想到最小割,但普通建图是(O(nm))的,大概过不了吧?
考虑一行一列随便跳,那么给行列建点,一片荷叶就是连接行列,此时点数就是(O(n))的了。
ARC075F Mirrored
这场只有F的原因是前几题都没啥意思……
考虑把(rev(n)=D+n)写成竖式的形式,枚举(n)的位数(可以发现位数最多是(D)的两倍),发现确定了最后(k)位就可以确定前(k)位,也就是一个对称着确定的形式。
但有一个东西叫做进位比较麻烦,所以我们设(dp_{i,0/1,0/1})表示做了低位的(i)位,第(i)位是否会给(i+1)位进位,第(len-i)位是否需要给第(len-i+1)位进位,的方案数,然后枚举某一位填什么来转移。(状态可能有一些加一减一不太对,不管了)
最后还要根据(len)的奇偶性分类讨论一下,感觉挺麻烦的,于是代码咕了/cy。
ARC076F Exhausted?
你很容易发现这是个求二分图最大匹配,你也很容易发现暴力建图会T。
想到前后缀优化建图,但这样复杂度就不是(msqrt n)了。鉴于网上没有题解这么写,我们就当它过不了好了。
那么怎么办呢?考虑霍尔定理:二分图有完美匹配的充要条件是对于左边任意一个集合(X),记(w(X))表示(X)能连到的右边的集合,都有(|X|le w(X))。
我们加(k)把椅子,显然会使得(w(X))变大(k),也就是要满足对于任意(X)都有(|X|le |w(x)|+k),即(kge max(|X|-|w(X)|))。
由于边的特殊性,(|X|-|w(X)|=|X|-m+max(max R-min L-1,0))。
显然(max R-min L-1<0)的时候取(X={1,2,...,n})最优,所以可以把(max)删掉。
然后枚举一下(max R),线段树维护(|X|-min L)的最大值即可。
ARC077F SS
设初始给的串是(SS),那么我们只关心(S)的变化情况。
如果(S)本身有循环节(len,len|n),那么容易发现(f(S))就是多加一个循环节到后面,我们特判掉。
否则,设(T)为(S)长度为(n-nxt_n)的前缀,可以发现(S)的变化情况就是(Sto STto STSto STSSTto STSSTSTSto cdots)。
找规律得第(i)个串就是第(i-1)个串拼上第(i-2)个串。证明我就不会了……
串的长度是(fib)数列,所以很快就可以爆(10^{18}),于是可以设(f_{i,c})表示第(i)个串(c)的出现次数,递推搞出来。
统计答案的时候先差分,然后可以拆成好多个串拼在一起,就做完了。
ARC078E Awkward Response
注意到这个询问的方式唯一有点恶心的就是有一个按字典序比较的限制,考虑去掉它。
你发现只需要确定(n)的位数就可以二分了。
位数怎么确定?你询问(10^k),一般来说他会返回([n>10^k])。
什么时候会有特殊情况?(n)自己就是10的幂,这时他永远返回1。
于是你问一下(10^{10})判一下是否是特殊情况,如果是就问一下(10^k+1),否则二分(n)的位数再二分(n)就没了。
ARC078F Mole and Abandoned Mine
之前写过了,见上。
ARC079D Decrease (Contestant ver.)
有趣的构造题。
一开始我看错题了,以为(kle 10^{16}),于是就想了个(n=2)的解:
考虑((a,a)),他会经过这样的变化:((a,a)to (a-2,a+1)to (a-1,a-1)),也就是经过2步使得两个数减1。
那么(k)为奇数怎么做呢?考虑((a+3,a)),他会经过这样的变化:((a+3,a)to(a+1,a+1)),经过1步之后变成上面那个形式。
这样在(k)较小的时候没有问题,但(k>2times 10^{16})时就不能这样做了。
考虑扩展一下,发现(n)个(a)会经过(n)步之后变成(n)个(a-1),所以只需要搞一搞余数。
我们令第一个数为(a+n+1),于是经过1步后变成了(n)个(a+1)。所以只需要给第一个数加上若干个(n+1),再给所有数减若干个1,就可以把余数表示出来。
然后你发现(ntimes n>10^3),你被卡了。感性理解一下,发现加(n+1)的操作好像可以加到任意一个数,于是做完了。
((k)较小的时候这么做可能会有一些边界情况,此时用(n=2)的更保险)
ARC079E Decrease (Judge ver.)
这题就没什么意思了,每次把最大的模(n),贡献加到其他数上,感性理解没什么问题。
应该就是因为操作的顺序不太重要,所以可以先对着一个数搞到小于(n)再搞其他的。
ARC079F Namori Grundy
咋回事啊?怎么F还没D有趣啊?
显然给的图是个基环外向树,显然树上的情况是确定的,只需要对环进行一些调整。
先对每一棵树dfs,得到环上的结果,设为(a_i)。这里的(a_i)不是最终结果,可能会由于环上数值的冲突而变大。
先判一下是否所有(a_i)均相等,如果是,那么容易发现偶环有解,奇环无解。
否则,考虑相邻两个相等的(a_i),此时需要把前一个(a_i)加1……一直这样做就一定有解?
错了,你发现后面那个(a)可能会变大,于是前面这个不用变,于是比较恶心。
注意到一定会存在连续的两个(a_i),使得前面的小于后面的。这时后面的怎么变大都不会影响前面这个(a_i),于是断环为链,肯定有解。
又因为没有输出方案,所以你用十分不严谨的思路得到的答案也是对的……
ARC080F Prime Flip
日常想不到差分,我菜死了……
差分之后仍然只会有(O(n))个点是1,并且每一次操作变成翻转(x,x+p),目标状态是全0。
感性理解,没有目的地把0翻成1是没有用的,于是只有下面三种操作:
- (|x-y|=p),此时只需一步。
- (|x-y|)为偶数,根据哥德巴赫猜想,需要两步。(2,4特殊,但(2=5-3,4=7-3))
- (|x-y|)为奇数且不为质数,此时可以先搞成偶数再用两步,一共3步。
发现最优解是用尽量多的1操作,然后再用2,最后用3。
1操作里的(x,y)奇偶性不同,所以搞个二分图匹配就没了。
ARC081F Flip and Rectangles
不知道怎么就注意到了一个性质:如果一个矩形里面不存在有奇数个1的(2times 2)的子矩阵,那么它就可以变成1。
为什么?显然,无论怎样变换都不会改变奇偶性,所以必要性有了。而如果你用列操作把第一行做成了全1,那么用奇偶性推一推就可以看出此时每一行的值都相同了。
然后就变成类似于最大子矩阵的东西,单调栈即可。
ARC082E ConvexScore
首先,你不能像我一样看错题……
看到(2^{n-|S|}),容易想到子集个数。
于是可以想到枚举点集,然后贡献到这个点集的凸包上。
于是就转化成有多少个点集存在凸包,改成多少个点集没有凸包,然后就很好做了。
ARC082F Sandglass
考虑每一次翻转中间的过程,要么是(xto min(x+t,X)),要么是(xto max(x-t,0))。
我们还发现一个性质:初始沙子越多,最后剩的越多。
于是就是一个一次函数向上敲一敲,向下敲一敲,肯定会变成两边平中间一个斜坡的样子。
ARC083F Collecting Balls
首先看到网格图,依据你对atcoder的理解,应该可以想到行列连边。
然后发现对于每个连通块,由于每个点必须删掉一条边,所以必然(m=n),即一棵基环树。
对于树边,显然点和边的对应关系是确定的。我们枚举环上是顺时针还是逆时针,然后考虑删除的先后关系有什么要求。
如果(x)要删除((x,y))的点,那么对于所有((x,k),k<y),都必须先删掉,所以(k)要比(x)先动。据此可以连出一个DAG。
可以发现,每个点的出度必然是0或1,并且连向的点是连通块里的点(于是每个连通块就是独立的了),所以每个连通块都可以连出一个内向森林。
于是每个连通块分别做出答案再合到一起就没了。
ARC084D Small Multiple
这都不会,丢人现场.jpg
你很容易往数论上面想,然而你建出([0,K-1])的点之后枚举(xto xtimes 10+y,yin[0,9]),把边建出来就做完了……
ARC084E Finite Encyclopedia of Integer Sequences
当(k)是偶数的时候容易想到({k/2,k,k,k,k,k,k,cdots})是最终答案。
当(k)是奇数的时候,我们先令(B={lceil k/2rceil,lceil k/2rceil,cdots})。
定义(f(X))为一个对数列进行的操作,使(X_ito K+1-X_i)。
可以发现,这几乎可以使得小于(B)的数列和大于(B)的数列一一对应,只有(B)的前缀例外。
于是可以知道(B)比答案只大了(n/2)(可能有+1-1),暴力退回去即可。
ARC084F XorShift
可以想象线性基的过程,也可以想象多项式(gcd)的过程,先把所有数都合并成一个,然后考虑最后剩下的数能组成的小于等于(X)的数的个数。
设(X)长度为(b),最后剩下的是(a),那么显然前(b-a+1)位随便乱填之后可以唯一对应到一种组合方法。
然而如果前面填的和(X)相同,那么最后可能会超出范围,所以还要特判一下。
...
由于最近很懒,可能暂时不会更新……
转载于:https://www.cnblogs.com/p-b-p-b/p/10834641.html
最后
以上就是温柔路人最近收集整理的关于AtCoder刷题记录ARC066C Addition and Subtraction HardAGC033C Removing CoinsAGC014D Black and White TreeARC063F Snuke's Coloring 2ARC068F SolitaireARC078F Mole and Abandoned MineAGC001F Wide SwapAGC003D AnticubeAGC003E Sequential operations on SequenceAGC0的全部内容,更多相关AtCoder刷题记录ARC066C内容请搜索靠谱客的其他文章。
发表评论 取消回复