最前面:

AT的题都很有思维难度,总结一下一些AT的常规操作

1.对于有操作的题目,如果正面推不行的话考虑倒推,将操作转化,寻找更好的性质

2.模型转化,看到某一种的计算的式子,需要考虑有没有更简化的模型可以达到相同的效果

3.补集转化,正难则反

4.分析题目性质,计数题要找到一些限制条件或者构造方案使得计数不重不漏

目标:稳定三题

比例:D:0/1  C:3/6 B:2/3

10.12 - 10.22

AGC47:Solved A,B,C,D Aim E

AGC46:Solved A,B,C,D

AGC45:Solved C Aim B

AGC44:Solved A,B,C Aim D

AGC43:Solved A,B,D Aim C

AGC41:Solved B Aim D

AGC40:Solved C

AGC37C Numbers on a Circle

首先AT常规操作,考虑倒推。那么现在题目就变为

1.选择一个下标i,将$b_{i}$减去左右两边的数

2.题目的目标变为从$b$数组变为$a$数组

由于$a,b$都是正整数,在任意一次操作之后,不能使$b$中的数变为负数,那么$b_{i}>b_{i-1}+b_{i+1}$,然后由于$b$中的值只会减小不会增加,所以$b_{i}>a_{i}$

现在考虑如果i满足上述条件,那么$b_{i}>b_{i-1},b_{i}>b_{i+1}$,对于$i-1,i+1$上述条件一定不满足(第一个条件),所以必须先对i进行操作,才能对左右两个下标进行操作,那么其实操作的大体顺序已经定下来了。相当于每三个分一个组,先把满足条件的数放到队列里,对其进行操作之后再判断一下旁边的两个数是否可以进行操作,如果可以就将点加入队列中。

看到官方题解和网上很多题解都是将所有的数都扔到一个堆里每次取出最大的数进行操作,其实并不需要这个堆,因为中间那个数不进行操作的话,左右两边的数一定不会满足条件,其实每一轮操作的顺序都是环上每隔三个数有一个数进行操作,由于每个数互不影响,所以操作顺序不会影响操作数量

复杂度$O(nlogMAX)$

代码

AGC37B RGB Balls

首先要考虑如何构造出一组最优的合法方案。考虑将每种球分组后以下标排序,然后将相同下标的三种球放在一起进行考虑

$a_1<a_2<a_3<...<a_{n-1}<a_n$

$b_1<b_2<b_3<...<b_{n-1}<b_n$

$c_1<c_2<c_3<...<c_{n-1}<c_n$

也就是将三种球的下标记录在$a$,$b$,$c$三个数组中,最终最优方案的答案就是$\sum_{i=1}^{n} max\{a_i,b_i,c_i\}-min\{a_i,b_i,c_i\}$

记$A$为$max\{a_i,b_i,c_i\}$组成的集合,$C$为$min\{a_i,b_i,c_i\}$,$B$为除$A,C$集合中其他的位置

可以发现$A$中所有元素都是对计算的值产生正的贡献,$C$中所有元素都是对计算的值产生负的贡献,$B$对计算的值无贡献

那么只要使最终的分配方案能使产生贡献的球都是$A,C$集合中的值即可

那么对于一个人,只要满足选到的球先是$C$集合中的,再是$B$集合中的,最后是$A$集合中的

从左往右枚举球,中途记录一下当前该选哪个集合的人有多少个,每次对答案乘上人数即可

代码

AGC39C Division by Two with Something

首先要将题目转化一下,对于一个二进制数,对其进行操作就是将最后一位取反放到前面,然后删掉最后一位

可以将这个二进制下的数取反复制到原数的前面,那么一个循环中的数可以通过截取所有得到的新数中长度为$n$的子串得到

考虑一个循环是怎么形成的,一个数通过$2n$次操作一定会变回原来的数,相当于前$n$次操作对原来的数进行了取反,后面$n$次操作对已经取反的数再进行一次取反,两次取反就会得到原来的串

再考虑循环在字符串上的意义,一个最短的循环就是拼接起来得到的那个字符串的最小循环节长度

设循环的次数为i,因为通过$2n$次操作一定回到原数,$n$次操作得到取反后的串,那么$i\mid 2n$,$i\nmid n$

循环节内部是有一个串和它的反串拼起来的

枚举$2n$的因子$i$,统计对于存在循环节为i的串的个数,注意是循环节不是最小循环节(最后容斥回去即可)

如果前$i/2$位比$x$的前$i/2$位小,那么之后循环的时候一定在$x$以内

那么只要判断一下前$i/2$位等于$x$的前$i/2$位,然后构造出前$n$个,比较与$x$的大小,如果比$x$小就对统计的个数$+1$即可

但不过此时统计的数量并不是最小循环节的数量,一个循环节会在循环节长度的倍数处重复统计,最后枚举其倍数容斥即可

代码

AGC36C GP 2

窝连最开始的限制条件都没想到

考虑最终的序列要满足什么条件才能被表示出来。很明显有$\sum_{i=1}^{n} x[i]=3m$,然后考虑一个数最大只能是$m$个$2$加起来,那么$\max_{i} x[i]\leqslant 2m$,由于是一个$+1$另一个$+2$,那么每一次最多改变一个数的奇偶性,那么$\sum_{i=1}^{n} [x[i]\%2=1]\leqslant m$

可以发现操作集合到满足这个限制条件序列的集合是一个满射,这种统计方案不重不漏

只考虑第一个和第三个限制条件,不考虑第二个,那么可以先在序列上若干个$1$,然后再在序列上放$2$,那么可以枚举放1的数量

$\sum_{i=0,(3m-i)\%2=0}^{m}C_{n}^{i}C_{n+\frac{3m-i}{2}-1}^{n-1}$

再考虑第二个限制条件,可以发现如果第二条件不满足,那么只有$1$个数不满足限制,那么考虑补集转化

枚举那个不满足的数有多大,再将剩下的数分配到$n-1$个位置里

再考虑一下第三个限制条件,可以发现,如果一个数大于$2m$,那么序列上不为$0$的数最多有$m$个数,即使全部都为奇数,也符合第三个限制条件,所以不用再考虑第三个限制条件

$n\sum_{i=2m+1}^{3m}C_{n+3m-i-2}^{n-2}$

两式相减即为答案

代码

AGC34C Tests

可以发现,如果一门考试比另外一个人高了,那么重要度一定要设为$u_i$,并且要学到满分,因为每一门考试都有一个$b_i$,只有超过$b_i$才能反超另外一个人,那么有一门考试已经超过$b_i$,那就要充分利用这门考试,去学其他的考试一定没有比把这个考试学到满分优(因为还要先学到$b_i$才可以);如果一门考试比另外一个人低,那么重要度一定要设为$l_i$

那么在这种策略之下,最多只有一门考试学习过但没有学到满分,其他的考试要么没有学要么已经学到了满分,原因是可能有边角料的存在,会使得有一门课不是满分

因为一开始每一门考试都是$0$分,那么与另一个人的差距就是$tot=\sum_{i=1}^{n} b_il_i$,如果把第i门课学到满分可以缩小的差距就是$v_i=(x-b_i)u_i+b_il_i$,那么以$v$从大到小排序,贪心的选择能缩小差距最大的那门考试,将初始的差距减去$v_i$

那么就是以$v$从大到小排序之后,找到最大的$k$,使得$\sum_{i=1}^{n}v_i\leqslant tot$

但是因为不一定能把初始差距减到$0$,那么就需要有一门考试来处理这个边角料,考虑枚举这个考试,分两种情况讨论

如果当前枚举的考试在前$k$个中,那么将当前枚举到考试替换成第$k+1$个考试满分,然后判断计算当前这个考试需要的时间

如果不在,直接计算即可

考虑如何计算一个考试需要花费的时间,如果边角料少于$b_il_i$那么重要度设为$l_i$,否则就设为$u_i$

我看到网上和官方题解都是带了一个二分时间,其实并不需要

还有我一开始写的程序被corner case卡WA了,需要特判所有$b_i$都是$x$的情况

代码

AGC47C Product Modulo

这种题AT很少见啊

看到这个式子会发现一般的处理方法很难进行处理,我比赛的时候打了一个整除分块,时间复杂度也假了。但可以发现这个模数给的很特殊,不是一般的$998244353$和$1e9+7$,那么从质数的性质出发

可以发现如果式子里不是乘法而是加法,那么是很好计算的,可以使用FFT或者其他的技巧计算,考虑如何把乘法变换为加法,很明显对乘数取一个$log$就可以化乘为加,那么考虑底数的选取

质数的原根$g$,保证在$1\leq i< p-1$,$g^{i}$两两不同,那么考虑用$g$作为底数,由于$p$不大,直接枚举次数,将每一个数取对数,然后用FFT加速加法运算(在每个数对应次数的位置$+1$,将这个多项式自乘$1$次)

代码

AGC47D Twin Binary Trees

一个由i,j两个叶子节点组成的简单环是i到j在树上的路径和p[i]到p[j]树上的路径组合起来的,如果记录一下每一个叶子节点到根路径上节点标号的乘积$fac$,那么i到j的路径上的节点标号乘积就是$\frac{fac_ifac_j}{LCAfac[father_{LCA}]}$

考虑枚举每一个LCA,分别来自每一个节点左右子树的叶子节点组成的路径的LCA是当前节点,那么在第一棵树上的乘积很好计算,直接枚举左右子树的叶子节点。对于第二棵树,考虑先遍历左子树,对于叶子节点$i$,在$p[i]$到根节点的路径上每一个节点都打上标记,标记上记录通过这个点的所有路径的乘积之和,这里的乘积要乘上第一棵树的贡献,枚举右子树的所有叶子节点,也在第二棵树的上遍历,遍历到的点记录的权值减掉上一次遍历到的点乘上当前标号,就是左子树的叶子节点和这个节点LCA的乘积之和,累计答案即可

代码

AGC24D Isomorphism Freak

首先需要发现如果要将两棵子树变成同构的话,所需要的最小的颜色数是两个子树深度的较大值,并且最小的叶子节点数就是每一层节点儿子数的最大值的乘积(因为要保证每一层都相同,而又不能删去节点,那么只能把这一层所有的节点的儿子都加到最大值,最后每一层乘起来就是叶子节点数)

那么考虑树的直径,当根定在树直径的中点时,所有子树深度的最大值不超过直径的一半$+1$

那么分类讨论

如果树的直径是奇数,那么直径的中点是一条边,那么以这条边左右两个端点分别作为两棵子树的根,统计每一层儿子数的最大值,在最后合并一下即可

如果树直径是偶数,那么直径的中点是一个节点,那么直接定这个中点为根,利用之前的做法统计出叶子节点个数,但是样例告诉我们还有另一种情况存在,由于此时直径为偶数,使直径$+1$并不会影响最小染色数,所以可以把直径$+1$,然后以边作为根,套用奇数的做法即可,最后取最小值即可

代码

ARC105C Camels and Bridge

刚D去了比赛时候没想出来

由于$n$给得非常小,所以考虑枚举每一种骆驼的排列方式,那么对于一种固定的骆驼排列,可以发现由于每一只骆驼都要走过桥,在桥上的一定是骆驼排列中的一段区间,对于每一个区间两个端点的骆驼之间的距离是有限制的。具体地,对于区间$[L,R]$,$x_R-x_L\geq max(l_k)(v_k<\sum_{i=L}^{R} w_i)$,这个式子可以在m中二分找出答案,考虑如果满足这所有的条件,那么这种排列骆驼距离的方式一定合法。其实这个只要$L$向$R$连一条权值为$max(l_k)$的有向边,那么原问题就是找DAG上最长路(因为最长路保证了$u->v$所有其他的限制都被满足了),$dp$即可

复杂度$O(n!n^2logm)$

代码

AGC46D Secret Passage

首先发现这个操作可以产生一些自由的$0$和$1$,这些可以任意的插入后面没有被操作影响到的串中,并且后面没有被操作影响到的串一定是原来串的后缀,那么记$ok[i][j][k]$为前$i$位被操作所影响到产生了$j$个自由$0$,$k$个自由$1$的状态是否合法,转移的时候枚举当前选出来的两个数,含多少个自由的$0$和多少个自由的$1$(0/1/2个),那么剩下的就是原来字符串里的$0,1$

然后再考虑将这些产生自由的$0,1$放到后缀里的方案数,记$dp[i][j][k]$表示$[i,n]$这个后缀未被操作所影响到,有$j$个自由$0$,有$k$个自由$1$插入其中的方案数,由于这个后缀一定是将$0,1$插入后得到串的子序列,那么考虑用子序列匹配的方式进行转移,就是$dp[i][j][k]$可以有$dp[i+1][j][k]$转移过来,然后如果当前这一位为$0$,可以向里面插$1$,可以有$dp[i][j][k-1]$转移过来,反之亦然

那么很自然的想,只要这个状态合法,就直接累计到答案中去,但这样会算重复,由于当后缀不断变成时,更长的后缀的方案一定被包含在短后缀的方案中(因为只要按顺序填$0,1$),那么从后往前扫描,每次有一个状态合法,将这个状态累计到答案中,之后把在这个基础上向前延伸的后缀的状态设为非法即可

代码

AGC45C Range Set

好题,想了好久才想明白

首先0,1是对称的,可以把初始串变为全1,然后交换$a,b$,这个问题和原来的问题等价,那么可以通过这个性质保证$a \leq b $

然后考虑什么样子的串是合法的,首先发现如果有一段连续的1的个数$\geq b$那么通过这一段1,可以向左右两边扩展,考虑在扩展的过程中要添加一段连续的字符,如果这个长度大于对应的限制,那么直接赋就行了;如果小于,先将这一段赋上,然后会有一段覆盖到之前的已经固定的字符,由于之前第一次扩展保证合法,并且赋0操作不会把这个初始的$\geq b$的区间全部覆盖,不断用之前的步骤调整回来就可以。那么通过这种操作一定可以把除了这个初始1串的其余所有位置所有可能性统计到,再考虑这个$\geq b$的1串(当然最终可以得到的串可能不止一个$\geq b$的1串,此处只以一个举例),由于$a \leq b$,那么可以在结束扩展之后在这个1串里面操作出某几段$\geq a$的0串,这样的得到的串一定也是合法的

那么我们先假设把所有$\geq a$的0串都赋成1,最后把原来的方案数乘上去即可。考虑DP,由于直接DP不方便,那么考虑反面

首先可以通过一个DP求出所有长度为n的1串可以被$\geq a$的0串分割成多少种不同的串(注意这里要保证开头和结尾一定为1,否则会和左右两端其他的0合成更长的,这样会重复统计,但对于前缀后缀的1串,只要保证一段为1就可以了,另一端是0或1都可以),设$f[i][0/1]$表示长度为$i$的1串被分割后最后一位为$0/1$的方案数,初始条件$f[0][0]=1,f[0][1]=0$,保证第一段不为0

然后用$dp[i][0/1]$表示第$i$位为$0/1$方案数,转移的时候$0/1$最长长度只能为$a-1,b-1$,然后判断一下1串是否为前缀后缀,如果是那么系数为$f[len][0]+f[len][1]$,否则为$f[len][1]$

代码

AGC44C Strange Dance

原来AGC也有数据结构题

考虑维护一个三进制Trie,对于S只要打标记交换1,2的位置,对于R,更新时先把当前节点的0,1,2换成2,0,1的顺序,然后考虑进位,递归更新2即可

代码

AGC40C Neither AB nor BA

发现如果直接按题意去分析不能删AB或BA的性质,是很难的。由于不能删的是相邻的两个字母,那么考虑将偶数位的A改为B,B改为A,然后会发现题目变成了不能删AA或BB,那么只要A或B在序列中出现大于$\frac{n}{2}$次就一定不行,那么最终答案为$3^n-2\sum C_{n}^{i}2^{n-i} $

代码

AGC16F Games on DAG

首先考虑每一个点求出其$sg$函数,只要$sg(1)=sg(2)$那么Alice必败,否则Alice必胜,那么先统计$sg(1)=sg(2)$的数量(因为数量少)可以发现,如果两个点的$sg$函数相同那么这些点之间一定没有边相连,那么就可以把点根据其$sg$函数值进行分层,并且要保证$1$号点和$2$号点要在同一层内,

由于n非常小,那么用状压来记录状态和枚举转移,记$dp[mask]$为当前$mask$点集已经在$sg$分层中的方案数,然后更新时枚举其子集作为最后一层$sg$的点,考虑具体如何转移,由于$sg$值较大的点一定要连向比其小$sg$层中至少一个点,那么枚举的当前子集,一定有其他已经在集合中的点连向它,那么计算出原来已经在集合中的点连向这些枚举的点的边的数量$w$,那么方案数就是$2^w-1$,然后当前枚举$sg$最小的这些点之间是不能连边的,但是可以连向$sg$函数值比它大的点,同样统计出边的数量,方案数为$2^w$

最终答案就是$dp[2^n-1]$

代码

AGC2F Leftmost Ball

一开始搞出了n^3的dp,但并没有什么用

这种放球不同的序列并且放球之间有限制,那么可以看作有向图的拓扑序,用连边来表示限制

考虑单独领出每种颜色的第一个球,在放完这个第一个球之后才能放这个颜色其他的球,然后再限制要按顺序放不同颜色的第一个球,然后最终算出答案后乘上n!即可

那么可以构建出这样一个图,用dp求解其拓扑序数,当解锁新的一列时,将这一列中的球穿插到还没有解锁的球中,组合数计算可以得到

代码

ATcoder Grand Contest总结的更多相关文章

  1. AtCoder Grand Contest 012

    AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...

  2. AtCoder Grand Contest 011

    AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...

  3. AtCoder Grand Contest 031 简要题解

    AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...

  4. AtCoder Grand Contest 010

    AtCoder Grand Contest 010 A - Addition 翻译 黑板上写了\(n\)个正整数,每次会擦去两个奇偶性相同的数,然后把他们的和写会到黑板上,问最终能否只剩下一个数. 题 ...

  5. AtCoder Grand Contest 009

    AtCoder Grand Contest 009 A - Multiple Array 翻译 见洛谷 题解 从后往前考虑. #include<iostream> #include< ...

  6. AtCoder Grand Contest 008

    AtCoder Grand Contest 008 A - Simple Calculator 翻译 有一个计算器,上面有一个显示按钮和两个其他的按钮.初始时,计算器上显示的数字是\(x\),现在想把 ...

  7. AtCoder Grand Contest 007

    AtCoder Grand Contest 007 A - Shik and Stone 翻译 见洛谷 题解 傻逼玩意 #include<cstdio> int n,m,tot;char ...

  8. AtCoder Grand Contest 006

    AtCoder Grand Contest 006 吐槽 这套题要改个名字,叫神仙结论题大赛 A - Prefix and Suffix 翻译 给定两个串,求满足前缀是\(S\),后缀是\(T\),并 ...

  9. AtCoder Grand Contest 005

    AtCoder Grand Contest 005 A - STring 翻译 给定一个只包含\(ST\)的字符串,如果出现了连续的\(ST\),就把他删去,然后所有位置前移.问最后剩下的串长. 题解 ...

  10. AtCoder Grand Contest 004

    AtCoder Grand Contest 004 A - Divide a Cuboid 翻译 给定一个\(A*B*C\)的立方体,现在要把它分成两个立方体,求出他们的最小体积差. 题解 如果有一条 ...

随机推荐

  1. 9.23 T1 tree

    题意描述: 给你一个长度为 \(n\) 的序列,让你从中选出 \(k\) 个数组成一个集合,定义这个集合的极限高度为\(a_i...a_k\) 的最大值. 让你求所有的集合极限高度 之和对 \(100 ...

  2. 【记】《.net之美》之读书笔记(二) C#中的泛型

    前言 上一篇读书笔记,很多小伙伴说这本书很不错,所以趁着国庆假期,继续我的读书之旅,来跟随书中作者一起温习并掌握第二章的内容吧. 一.理解泛型 1.为什么要使用泛型?-----通过使用泛型,可以极大地 ...

  3. java之网络编程1-Tcp

    一,了解之前先了解一下网络基础 首先理清一个概念:网络编程 != 网站编程,网络编程现在一般称为TCP/IP编程 一般的网络编程都称为Socket编程,Socket的英文意思是"插座&quo ...

  4. Prometheus第一篇:Prometheus架构解析

    Prometheus是新一代的监控系统解决方案,原生支持云环境,和kubernetes无缝对接,的却是容器化监控解决方案的不二之选.当然对传统的监控方案也能够兼容,通过自定义或是用开源社区提供的各种e ...

  5. C# OOP编程

    1:面向对象的概念:什么是类.对象.以及类与对象的关系. 面向对象三大特征: 封装/继承/多台 2:封装性: 用访问修饰符来体现封装性. Public 公共的/ private 私有的/Protect ...

  6. 警惕char类型直接相加

    今天在写某个程序需要对两个数字字符串进行相加操作,比如字符串1:12345,字符串2:23456.需要1和2相加.2和3相加.就是两个字符相同位置的数进行相加. 这个一看很好完成,写一个for,然后取 ...

  7. spring-boot-route(十五)整合RocketMQ

    RocketMQ简介 RocketMQ是阿里巴巴开源的消息中间件.目前已经贡献给Apache软件基金会,成为Apache的顶级项目. rocketMQ基本概念 1. Producer Group 生产 ...

  8. GUI版本的emacs

    概要 emacs 配置 X11 配置 输入法配置 spacemacs 中的配置 fcitx 汉字显示方块的问题 总结 优势 劣势 概要 之前一直使用 terminal 版本的 emacs, 性能和显示 ...

  9. Verilog基础入门——Vivado工程创建(三)

    Verilog基础入门--Vivado工程创建(三) Vivado是Verilog语言的一个集成环境,目前使用的版本为英文版,简单介绍一下在Vivado中创建一个工程并写入源文件 [配置] win10 ...

  10. 习题3-4 周期串(Periodic Strings, UVa455)

    #include<stdio.h> #include<string.h> char s[100]; int main() { int T; scanf("%d&quo ...