计时引爆摩天轮
POJ1149 Pigs
考虑网络流,我们直接连边感觉不是很可做,考虑依次将猪圈里面的猪寄存在最后一个买的人手里面,然后每一个人到上一个人那里去买,这样子就可以了.
CF119D String Transformation
神仙字符串题.反正我是做不出来的.
考虑现在我们的问题变成,枚举一个(i),然后求满足条件的最小的(j).
这个问题我们建出两种串:(sA=r(A)+ch+B,sB=B+ch+A),这里的(ch)表示的是一个在串里面没有出现过的字符.
对于(sA)求一个(nxt)数组,对于(sB)做一个( ext{z-function}),这个时候不难发现:
我们的(j)的最小值就是取到(n-(len=p[2*n-i-1])),此时只需要判断(z[n+i+2]>=n-i-len-1)即可.
具体你考虑前面式子的意义是你最长的在可以是多少,即(j)的最小值.后面式子的意义为对应位置的最多匹配的长度.
也就是两端都最大化,只需要判断在这种情况下是否可行即可.
至于正确性,唯一需要考虑的是(j)最小的时候不满足要求,当(j)变大的时候,就算第一个条件可以满足,后面的(Z)函数只会元而来越差.
[TJOI2018]游园会
考虑设(f_{i,s,j})表示前(i)个位置,现在匹配的差分情况是(s),最后面有长度为(j)的"NOI"串.
这个东西可以预处理字符与状态的转移,然后枚举字符转移即可.
我感觉这个题目应该有很多种写法但是我是真的不想写了.
[NOI2016]优秀的拆分
首先直接二分+Hash有95分.
讲道理如果NOI赛场上真的有95这种牛逼的部分分我一定不会去Rush正解.
然后考虑枚举(A)串长度,每(len)个点就放一个关键点,那么一个(AA)串一定过两个关键点.
这样子我们求出相邻两个关键点的(lcs)和(lcp),然后直接差分+前缀和即可.
「NOI2016」循环之美
神仙题,为什么我总是不会这种数论题啊.
考虑一个结论,一个数如果在(K)进制下循环,那么一定是分母与(K)互质.证明不会.
剩下的就是莫比乌斯反演+递归+杜教筛了.
「NOI2017」蔬菜
首先考虑贪心,我们每一次一定选的是带来贡献最大的,然后考虑选一个一定是在最后一天选.
所以只需要用一个堆和并查集维护上述操作即可.
「清华集训 2017」小 Y 和二叉树
考虑中序遍历的第一个点一定是度数<3的编号最小的点,令它为(r),这样子的话,我们只需要找到原树的根.
从(r)开始考虑每一个点的情况,那么只需要判断这个点的出边对应的点是父亲还是右儿子,然后不断跳父亲找根.
找完根之后,问题变成了如何最小化这个序列,只要判断左右儿子需不需要交换即可.
「JSOI2018」战争
闵科夫斯基和模板题,我们只需要求一个闵科夫斯基差然后判断一个点是否在这个差的凸包内部即可.
[HNOI2012]三角形覆盖问题
有一个非常简单的思路,考虑直接上自适应辛普森法,然后算(F(x))的话,就直接求区间并即可.
但是发现这样子只有50pts,考虑其他做法.
听说有一个很神仙的(O(nlog{n}))的平衡树做法但是我不会,所以我直接写了个暴力.
「CEOI2017」Mousetrap
首先考虑以(t)为根,那么我们现在就要让老鼠从(m)跳到根节点.那么考虑一个老鼠如果向下进入了一颗子树的叶子节点,那么很明显,他就出不来了,这个时候我们可以把外面的路都封住,然后把他到根的路径清理好.
现在我们只需要处理出来一个(f_u),表示(u)往子树里面走然后在回到(u)的操作数;(g_u)表示(u)到根节点需要封死的路的数量.
然后你就考虑二分答案,然后你只需要把(m)到根的点都抠出来然后算就可以了.
「NOI2018」屠龙勇士
首先我们可以提前算出砍每一条龙所使用的剑,接着问题变成了求一堆(x imes atk_i equiv a_i( ext{mod} p_i)).
想一想这个东西怎么求?我们可以把(atk_i)移到右边,就变成了一个(excrt).
注意有个问题就是这个只能够处理(a_i le p_i)的情况,但是当(a_i>p_i)的时候,(p_i=1).所以直接数据分治即可.
POJ2778 DNA Sequence
这个题其实有点东西.可能是我太菜了
考虑建个病毒串的(AC)自动机,然后把(fail)数组跑出来.
现在想一想,新加入一个字符到后面等同于什么?
我们如果没有匹配任何一个,其实就是在根节点后面加,否则就是在(AC)自动机上面的一个节点上面加.
所以你接着想,我们可以把每一对节点之间的转移处理出来,然后跑(n)次就是答案了.
「TJOI / HEOI2016」字符串
首先可以二分答案,我们考虑现在要求的是(s[a..b])中是否存在一个子串和(s[c..c+len-1])相等.
建出后缀自动机,可以很方便的倍增求出(s[c..c+len-1])对应点的位置,接着想一想,我们要判断是否存在一个(endpos)在(a,b)之间,这个可以线段树合并.
那么复杂度就是(O(Qlog^2 n+nlog {n})).
我服了,最优解是我的(frac{1}{40})的时间.最优解还是暴力跳的.
「雅礼集训 2017 Day7」事情的相似度
首先考虑我们要求的是([l,r])内的前缀的(lcp)的(max),那么可以把询问打到右端点然后维护后缀最大值.
剩下的事情就是如何维护后缀最大值了.考虑每增加一个字符,等于是加一段子串对吧.我们就可以不断跳父亲然后更新(lca)处的答案了.这个过程和(access)类似,所以直接(LCT)维护即可.
「TJOI2015」弦论
题目名字只是吓你的.
就考虑直接建个(SAM),然后在后缀树上面判一下(siz)即可.
仰望半月的夜空
练一练( ext{SA}),考虑对于每一个长度对应的一定是一段(sa),然后你就可以自然地想到,如果有一些长度都满足(geq i)的,那么要选一个最小的.
所以可以二分(geq i)的,然后(st)表算答案.
小清新人渣的本愿
很有意思的一道题目.
首先考虑可以莫队,这样子我们就只需要维护能否存在(x1+x2=X,x1-x2=X,x1*x2=X).
很明显,(opt=3)的可以直接枚举约数然后随便做是吧.
看到这个(x1-x2=X),我们不难想到用(bitset)维护.
最后还有(x1+x2=X)的操作,我们可以用数学知识稍微转换一下:
这样子也可以直接维护一个(MX-x)的(bitset)就行了.
CF666E Forensic Examination
一道更加有意思的题目
我们首先考虑对(T)串建个广义( ext{SAM}).
接着我们顺序枚举(S)串的位置,考虑每一次就跳到对应前缀的位置.
很明显对于右端点在(i)的串,等同于是一个子串对吧.这样子我们就可以倍增跳对吧.
找到对应节点之后,考虑我们要求的东西是什么?最小众数和对应数出现的次数.
直接用权值线段树维护然后线段树合并即可.
注:
-
这里广义(SAM)的建法有三种,如果不是给一个(Trie)让你建广义(SAM)的话,你都可以用(last=1)来建.
-
如果给了你一个(Trie),你就直接从父亲的(last)来就可以了,不然复杂度会出现一些问题.
[POI2007]ZAP-Queries
数论分块即可.
[国家集训队]Crash的数字表格 / JZPTAB
略.
「ZJOI2014」力
首先把(E_i)的式子化简,然后把(q)数组反转一遍做5次(DFT)即可.
「TJOI2018」教科书般的亵渎
很明显我们一共需要(m+1)次亵渎,考虑拆分成(m+1)次操作,对于每一次操作单独计算贡献.
很明显,答案就是(sum_{i=1}^{n-a_i}i^{m+1}),但是两次操作之间可能会计算重复贡献,直接减去即可.
复杂度如果(O(1))算组合数就是(O(m^2))的.
[HAOI2011]Problem b
和POI2007那个题目一样,直接拆成四个询问即可.
「HAOI2018」奇怪的背包
yyb强啊.
考虑每一个物品选的贡献一定是(gcd(v_i,P))的倍数,所以我们可以把所有的数都变成(gcd(v_i,P)).
那么接着想一想,我们只需要算出来每一个(P)的约数的贡献即可.
这个东西可以直接(O(sigma^2(P)))做,暴力容斥即可.
最后再把(sum_{i|d}f_i)的贡献加起来即可.
付公主的背包
重做一遍,感觉自己确实理解了这个题目了.
首先我们考虑这是一个完全背包计数,那么我们可以把背包写成生成函数的形式,即:
接着我们想一想,这是一个物品的贡献,我们知道背包就是:
看到这个(prod)我们很不爽,把它变成(ln)然后尝试(sum).
那么现在变成了对(-ln(1-x^{V_i}))计算了,设(F(x))为它,有:
开个桶算个系数即可.
P4238 【模板】多项式乘法逆
已经沉沦到开始打板子了吗
P4725 【模板】多项式对数函数(多项式 ln)
P4726 【模板】多项式指数函数(多项式 exp)
P5205 【模板】多项式开根
P5245 【模板】多项式快速幂
「SNOI2019」纸牌
考虑设(f_{i,j,k})表示当前考虑了前(i)张牌,有(j)个((i-1,i,i+1)),(k)个((i,i+1,i+2))的牌,此时如果要向后转移,只能是:
仔细分析,不难发现(0 le j,k le 2),那么我们就可以把这个(9 imes 9)的转移矩阵写出来然后矩阵快速幂即可。
有的牌可能没有很多个,我们直接预处理仅有(i)张牌的情况即可。
「GXOI / GZOI2019」与或和
首先考虑拆位,那么接下来我们只需要处理有多少个全(0)子矩阵即可。
这个可以使用单调栈较快的计算以每一个端点为右下角能够形成的全(0)子矩阵来解决。
「GXOI / GZOI2019」特技飞行
我真的没有脑子了,数据范围都不看就开始想题目。
首先看数据范围,注意到交点数不超过(10^5),可以用(set)处理出所有的交点。
接着考虑可以把所有的(c)的贡献都算出来。
剩下的就只有是使用对换还是擦身的问题了。
- (a ge b),显然最多使用(a)就是答案最多,最多显然就是逆序对数。
- (a < b),此时我们要将一些对象交换变成擦身而过,一个置换里面是需要交换的,所以交换次数为(sum_{i=1}^klen_i)。
此时只需要码码码即可。
「BJOI2019」删数
首先考虑没有修改操作,那么有如下结论:
如果将((x-cnt[x]+1,x))当做线段,那么答案就是([1,n])中没有被覆盖的位置。
证明大概就是先证这个的可行性,再证这是下界,你一定是要把所有的位置都覆盖才能够把序列长度从(n o 0)。
那么我们只需要维护线段树上的最小值和最小值对应的区间长度,这个就是基本的线段树练手题。
加入修改考虑一个区间平移操作我们可以通过整体打标记维护,然后修改(1)和(n)的标记。
单点修改直接修改即可。
「BJOI2019」奥术神杖
首先考虑在(AC)自动机上(dp),那么我们可以设(f_{i,j})表示当前匹配到了(i)这个位置,在自动机的(j)位置的最大贡献。
但是这个(sqrt[c]{prod v_i})好像不能(dp)。
设(ans=sqrt[c]{prod v_i}),有一个极其自然的高中数学思路就是同时取(log),这个时候就变成了(sum_{i=1}^k{v_i-ans})了。
看到这个形式不难想到(01)分数规划,直接二分然后按照上述(dp)判断即可。
「十二省联考 2019」春节十二响
首先考虑一条链的做法,一定是将左边的最大值和右边的最大值放一起,左边的次大值和右边的次大值放一起……
然后如果放在一颗树上面,就可以想每一次把儿子的链合并然后变成一条新链,这样子就可以做了。
最后直接计算答案。
「HNOI2019」序列
「ZJOI2019」语言
我被去年的我吊着锤了,去年还会写60pts,今年会写0pts(
首先考虑对于每一个点,能够和他开展交流的城市我们称他为连通,有一个显而易见的结论:
连通的城市是一棵最小生成树。
那么我们只需要按照(dfs)序维护这个生成树。考虑(sum(siz-1))就是答案的两倍,而生成树的(siz)只需要维护两两相邻点间的(dis),所以可以用线段树维护。
这个时候我们要把儿子合并到父亲上去,线段树合并即可。
「SDOI2019」热闹的聚会与尴尬的聚会
这就是一道**题
首先不难发现第二问可以直接输出最大独立集,因为我们要求的是((p+1)(q+1) > n),所以最大化(q)一定没有问题。
然后现在要求这个(p),可以二分然后类似(bfs)一样判断。
最大独立集直接( ext{random_shuffle})即可。
「SDOI2019」快速查询
又是一道憨憨题。
考虑首先可以离散化,那么我们剩下来的操作可以用线段树维护:
维护两个标记((tag,mul))表示对于一个数(x),答案是(x*mul+tag)。
那么除了区间赋值之外的标记都可以很好的维护。
考虑区间赋值直接暴力和上一次操作之间的所有单点修改全部改掉就行了,这样子的复杂度(sum)是不会超过(Q)的。
TopCoder - 14634 ExtremeSpanningTrees
不想写代码只想口胡,迫 于 生 计
首先那个生成树就是一堆限制关系对吧。
现在把限制关系全部都抠出来,显然可以整体二分。
对于一个二分,直接网络流判断连哪一边然后再根据选的(S)还是选的(T)决策即可。
「2018 集训队互测 Day 2」有向图
首先按照保序回归的套路,可以整体二分。
那么怎么判断呢?网络流。
如果是个环你就直接钦定一个点为(0)然后递推下去,如果不是的话你就直接按照树的做法(dp)即可。