小W的神奇口胡

这里会口胡一些乍一看会做,或者没时间写(或者懒得写)的题目,或者一道题目的其他解法,应该很少更新,不用等了…

【BZOJ3456】城市规划-分治NTT
测试地址:城市规划
题目大意:nn个点带标号简单无向连通图(即无重边,无自环)的数目。
做法: 本题需要用到分治NTT。
实际上这题做法挺多的,我用多项式求逆写了这一题,据说还可以用多项式求ln写,有待学习。
f(n)f(n)为我们要求的答案,g(n)g(n)为不要求连通时的答案,显然g(n)=2Cn2g(n)=2^{C_n^2}。那么有如下递推式:
f(n)=g(n)i=1n1Cnif(i)g(ni)f(n)=g(n)-\sum_{i=1}^{n-1}C_n^if(i)g(n-i)
实际上是在枚举点11所在的连通块大小ii(这个在多项式求逆做法中也差不多)。
把组合数拆开后有:
f(n)=g(n)n!i=1n1f(i)i!g(ni)(ni)!f(n)=g(n)-n!\sum_{i=1}^{n-1}\frac{f(i)}{i!}\cdot \frac{g(n-i)}{(n-i)!}
后面的和式显然是一个卷积的形式,然而这个卷积涉及ff自己,所以使用分治NTT即可,我们就以O(nlog2n)O(n\log^2n)的时间复杂度完成了这一题(但多项式求逆O(nlogn)O(n\log n)…)。

【HDU5201】The Monkey King-容斥
测试地址:The Monkey King
题目大意: mm只猴子分nn个桃,其中猴王必须分得严格最多数量的桃,问方案数。
做法: 本题需要用到容斥。
哇,我怎么这么菜,连这种容斥水题都看不出来了…
首先显然枚举猴王能得到的桃子数量ii,要求剩下的猴子得到的桃子数都小于ii的方案数,直接算不行就容斥,强制某些猴子得到的桃子数大于等于ii,然后剩下的分配就是经典的隔板法了,因此我们有以下式子:
i=1nj=0ni1(1)jCm1jCnij+mj2mj2\sum_{i=1}^n\sum_{j=0}^{\lfloor\frac{n}{i}\rfloor-1}(-1)^jC_{m-1}^jC_{n-ij+m-j-2}^{m-j-2}
暴力计算即可,时间复杂度为调和级数O(nlogn)O(n\log n)

【HDU5773】The All-purpose Zero-贪心+DP
测试地址:The All-purpose Zero
题目大意: 给定一个序列,有若干个00,可以把00变成任意数字,问此时能得到的最长上升子序列长度。
做法: 本题需要用到贪心+DP。
这题需要注意到一个非常重要的结论:把00全部拿上一定是不亏的。因为对于任意一个不拿完00的上升子序列,我们都能把某个数字改成对应位置的00来表示。因此我们直接默认取走全部的00,而对于剩下的序列,因为00默认取了,那么跨过若干个00时,两个数的差就必须大于等于中间00的个数+1+1才能接上,那么我们直接把每个数减去它前面00的数量,对这个序列做LIS,然后加上00的数量即可,时间复杂度为O(nlogn)O(n\log n)
不过从一般的求LIS的DP上想也是可以的,我们在DP中要维护一个数组d(i)d(i),表示长为ii的上升子序列的末尾元素的最小值,不难发现dd应该是严格递增的。而在遇到一个00时,事实上dd会产生这样的变化:先全部+1+1,再整体右移一位。所以我们以这样的方式也可以得到和上面差不多一样的结论。

【BZOJ2924】Flat Broken Lines(POI1998)-Dilworth定理+DP
测试地址:Flat Broken Lines
题目大意: 题目上有nn个点,定义一条平直折线为,每一条线段与xx轴的夹角都在正负4545度以内的折线,问至少需要画多少条平直折线才能覆盖所有的点。
做法: 本题需要用到Dilworth定理+DP。
考虑一个点,它下一步能画到的区域是一个夹角是直角的四分之一平面,所以我们把整个坐标系转4545度,这样就可以变成一个二维平面上的最小偏序路径覆盖问题,用TJOI2015-组合数学那道题的做法做即可。

【BZOJ5093】图的价值(LYDSY1711月赛)-NTT+第二类斯特林数
测试地址:图的价值
做法: 本题需要用到NTT+第二类斯特林数。
容易想到分开计算每个点的贡献,于是我们枚举这个点的度数,其它边随便连,我们就能得到:
ans=n2Cn12i=0n1Cn1iikans=n\cdot 2^{C_{n-1}^2}\cdot \sum_{i=0}^{n-1}C_{n-1}^i\cdot i^k
这个式子的后半部分,在CF932E-Team Work那题中推过了,用第二类斯特林数以及NTT即可O(klogk)O(k\log k)算出答案,于是我们就解决了这一题。

【BZOJ4245】OR-XOR(ONTAK2015)-按位贪心
测试地址:OR-XOR
做法: 本题需要用到按位贪心。
要使得最后或起来的和最小,想到按位贪心,从高到低枚举每一位能不能为00,如果能为00就为00。那么我们怎么判断呢?实际上我们是要把序列分成mm段,每段中该位的异或和都要为00,那么我们可以求出序列的异或前缀和,选取每个当前位为00的为右端点,看能不能选够mm个就好了,要注意的是第nn个前缀和如果当前位不为00则直接判错。
还有一点要注意,当我们选定了一些位要为00,我们判断的时候就要同时考虑这些位,只有这些位同时为00的点才能选为右端点。于是我们就解决了此题。

【LuoguP3986】斐波那契数列-扩展欧几里得
测试地址:斐波那契数列
做法: 本题需要用到扩展欧几里得。
虽然是道提高难度的题…但是偶然看到发现很有意思就写一下…
不难注意到数列中每一项都可以表示成aFn+bFn+1aF_n+bF_{n+1}的形式,其中Fn,Fn+1F_n,F_{n+1}为斐波那契数列中相邻的两项。所以我们要求的就是有多少对a,ba,b,使得kk可以表示成上面的形式。
斐波那契数列增长很快,所以我们可以直接枚举这相邻的两项(显然是log\log级别的),然后用扩展欧几里得乱搞求出每种情况下解的数目即可。

【BZOJ5415】归程(NOI2018)-最短路+Kruskal重构树
测试地址:归程
做法: 本题需要用到最短路+Kruskal重构树。
这题在考场上就A了,不想再写一遍了。
每个询问实际上是求,只走高度大于pp的边,从点vv所能走到的点中,从点11开始的单源最短路值最小的是多少。所以我们用Dijkstra算法算出单源最短路(SPFA已死,勿念)。接下来这个强制在线的询问,就和ONTAK2015-Peak那道题的加强版基本上一样了,用Kruskal重构树即可。

【BZOJ5418】屠龙勇士(NOI2018)-扩展中国剩余定理
测试地址:屠龙勇士
做法: 本题需要用到扩展中国剩余定理。
说得这么厉害,实际上就是合并模线性同余方程的通用方法,直接搬上来就差不多了。注意血量除以攻击力会对攻击次数限制一个下限。
(但是在考场上还是爆成75…为什么啊…)

【CF700E】Cool Slogans-SAM+DP+主席树
测试地址:Cool Slogans
题目大意: 给定字符串SS,要求一个最长的序列AA,使得AA中的每一项都是SS的一个子串,且对于所有i>1i>1,满足Ai1A_{i-1}AiA_i中出现两次以上,求AA可能的最长长度。
做法: 本题需要用到SAM+DP+主席树。
按照直觉,我们觉得这个题和SAM或后缀树有关。然后要看出一个显而易见的结论:
一定存在一个最优的序列AA,其中每一个子串在SS中出现位置的右端点全相同。
这个结论很好证明,如果右端点不相同,就把它削成相同的即可。
那么显然一个最优的序列AA中的子串,在后缀树上是从根到某个前缀节点链上的某些点。这就启示我们在后缀树上DP,只不过这个DP和常规的从下到上的树形DP不同,这时我们应该从上到下DP。那么问题就来了,本质不同子串的数量可能很多,我们不可能定义一个对子串而言的状态,但是结果确实又和这个相关,那要怎么办呢?这时候就需要第二个结论:
一定存在一个最优的序列AA,其中每一个子串都是在后缀树上对应的点能表示的子串中最长的。
为什么能这样说呢?因为如果有一个最优解中,其中一项不是对应点中最长的子串,由于该点中最长子串和这项的RightRight集合完全一样(因为在同一个后缀树的点中),所以我们完全可以把该序列修改成一个满足条件的解,且不会变差。
有了这个结论后就好做了,令f(i)f(i)为根到点ii的路径上最多能取多少个点作为序列AAg(i)g(i)表示上面取的点中最下面的点。那么在转移时,只需要考虑g(i)g(i)这点的最长串是不是在f(son)f(son)这点的最长串中出现了两次即可,类似于NOI2018-我的名字用主席树判断即可。这样我们就解决了这一题。

【LuoguP3960】列队(NOIP2017)-动态开点线段树
测试地址:列队
做法: 本题需要用到动态开点线段树。
我们发现操作过程中,首先最右边一列没有任何规律,因此只能用动态开点线段树或树状数组维护最右边一列的序号。去掉最右一列之后,每一行有两个部分,左边的部分是原来在这一行内,还没有出过列的那些同学,右边的部分是新插入该行的部分。对于左边的部分,由于编号整体有序,因此我们只需要用动态开点线段树维护已经出列的那些同学,就可以在这个部分内定位了。而对于右边的部分,直接用动态开点线段树维护即可。显而易见的是,使用动态开点线段树的次数一定是O(n)O(n)的,因为每次操作需要:在行内定位,修改行的对应信息,然后在最右一列中定位行,将对应的位置插入行的信息中去,再将它从最右一列的信息中删除。这些操作都是O(logn)O(\log n)的,因此总的时间复杂度就是O(nlogn)O(n\log n)

【BZOJ5017】炸弹(SNOI2017)-线段树优化建图+SCC缩点+拓扑排序
测试地址:炸弹
题目大意:n(5×105)n(\le 5\times 10^5)个炸弹,每个炸弹有一个坐标xix_i和一个半径rir_i,当一个炸弹爆炸时,会同时引爆坐标在[xiri,xi+ri][x_i-r_i,x_i+r_i]内的所有炸弹,对每个炸弹求,当引爆这个炸弹后有多少个炸弹会爆炸。
做法: 本题需要用到线段树优化建图+SCC缩点+拓扑排序。
直接暴力连会连出O(n2)O(n^2)条边,炸得透透的。这时我们一看,实际上就是每个点向一个特定区间内的点连边,于是我们使用线段树优化建图的思路,多开一棵线段树,线段树中的点从父亲连向儿子,而每个叶子节点向对应的真点。于是从一个点连向一个区间的点就很简单了,直接从真点向线段树中区间对应的O(logn)O(\log n)个点连边即可。于是再使用SCC缩点和拓扑排序就能很轻易地算出答案了,时间复杂度为O(nlogn)O(n\log n)

【BZOJ2296】随机种子-数论+构造
测试地址:随机种子
题目大意: 对一个数x(106)x(\le 10^6),找到一个ans(1016)ans(\le 10^{16})使得ansans的十进制表示中包含0,1,2,...,90,1,2,...,9并是xx的倍数。
做法: 本题需要用到数论+构造。
我们发现答案是1616位的正整数,所以在最高1010位填1,2,3,..,9,01,2,3,..,9,0,再用剩下六位数把正整数补齐成xx的倍数即可。注意x=0x=0时无解。

【HDU6048】Puzzle-思维
测试地址:Puzzle
题目大意: 通过题目中所给的方法构造一个类似八数码的n×mn\times m数码谜题,求这个谜题可不可解。
做法: 本题需要用到思维。
要做出本题,要证(猜)出一个惊为天人的结论:将格子的数字按照从左到右,从上到下的方式写出(00不写),如果逆序对的奇偶性和最后的局面相同就可解。(这怎么可能是人能猜得出来的结论啊…)
大概的证明思路是,首先空格向左或向右对排列没有影响,而向上和向下的次数之和一定是偶数(因为空格的起点和终点相同),因此排列的逆序对数的奇偶性不会改变。
证明了这点,再证明出同奇偶性的状态可以互达就行了。根据某种直觉(实际上就是我看不出来),任何局面都可以被移成,只有右下角2×22\times 2的区域没有确定的状态,强行枚举66种情况,发现结论成立。
于是我们只需要求出逆序对数即可,而题目中给的构造方法有一定规律,直接用等差数列求和公式等计算即可。

【HDU5114】Collision-思维+数论
测试地址:Collision
题目大意: 两个小球在一个矩形框里移动,一开始速度都是(1,1)(1,1),碰到矩形边框会进行不消耗能量的碰撞,然后按反射定律确定速度方向,问两个小球第一次相互碰撞时所在的位置。
做法: 本题需要用到思维+数论。
首先,因为碰撞点有可能是在两个整坐标之间的中点,所以为了方便起见,我们一开始就将所有坐标乘22
接下来,显然应该将速度正交分解来考虑。对于xx坐标来说,两个小球xx坐标相同当且仅当:x1=x2x_1=x_2,或者(x1+x2+2t)mod  2x=0(x_1+x_2+2t)\mod 2x=0。至于原因,你画一下图就可以看出来了。对于yy坐标也同理。
于是我们讨论四种情况(因为上述每种条件都有两种情况),其中包含至少一个x1=x2x_1=x_2这种条件的情况比较容易计算,主要是第四种情况,也就是x1x2x_1\ne x_2而且y1y2y_1\ne y_2的情况。
上面的(x1+x2+2t)mod  2x=0(x_1+x_2+2t)\mod 2x=0可以写成x1+x2+2t=2xk1x_1+x_2+2t=2x\cdot k_1yy的那个也可以列成这样的式子,于是我们就可以以tt为等量关系,列一个关于k1k_1k2k_2的不定方程。这样我们用扩展欧几里得求出一组解后,再进行微调得到最小的非负解tt即可。

【HDU6040】Hints of sd0061-思维+nth_element
测试地址:Hints of sd0061
题目大意: 一个nn个元素的数列aa,若干个询问bib_i,对每个询问求aa中第bi+1b_i+1小的数是多少。bib_i满足,当bibj,bi<bk,bj<bkb_i\ne b_j,b_i<b_k,b_j<b_k成立,则bi+bj<bkb_i+b_j<b_k成立。
做法: 本题需要用到思维+nth_element。
如果只有一个询问,显然应该用nth_element,这个算法的思想类似快速排序,不过因为每次数据范围减半,所以该算法在随机情况下是O(n)O(n)的(题目中的aa数列也可以近似认为是随机的)。
而因为bib_i满足题目中所求的性质,我们很快可以发现,将bb排序后所得的序列的增长速度和斐波那契数列相似。因此,我们只需要从大到小处理询问,每次处理完后,就不再涉及后面无用的区间,这样总的来说是O(n)O(n)的。

【HDU5821】Ball-思维
测试地址:Ball
题目大意:nn个盒子,每个盒子里最多放一个球,每个球有颜色。现在给出起始和目标的颜色序列,问能不能按照如下的一种操作方式从起始颜色序列得到目标颜色序列:给定mm个操作,每个操作将区间[li,ri][l_i,r_i]内的盒子里的球取出来,再任意地放回这些盒子里去。
做法: 本题需要用到思维。
首先我们知道,如果有解,则一定存在一种操作方式,使得同种颜色的球出现的相对顺序不变(因为如果相对顺序能发生变化,那它一定能不发生变化)。因此我们给目标序列中的每个球标号,再返回去推出起始序列中每个球的标号,于是每次操作我们就只需贪心地对区间内的标号进行排序即可,如果最后能得到所要的排列就说明有解,反之无解。

【HDU5873】Football Game-思维
测试地址:Football Game
题目大意:mm个球队,每两支球队间进行一次且仅一次比赛,获胜的一方积22分,输掉的一方不积分,如果平局就两个队伍各积11分。现给出每个球队最后的总积分,问这种积分情况有没有可能出现。
做法: 本题需要用到思维。
我们先来看合法的得分情况有什么必要条件。很显然,在ii支球队之间的所有比赛中,积分的总数是i(i1)i(i-1),那么最后这ii支球队的总积分显然应该大于等于i(i1)i(i-1)才是合法的。当i=ni=n时,就要求总积分等于n(n1)n(n-1)才是合法的。因此我们可以把队伍的总积分排序,然后看最小的ii个积分之和是不是满足上述条件来判断必要条件是否合法。接着,我们发现,这个必要条件同时也是充分条件,因为在满足上述条件的情况下,分数的分配其实是任意的。这样我们就解决了这一题。

【HDU4803】Poor Warehouse Keeper-贪心
测试地址:Poor Warehouse Keeper
题目大意: 一个屏幕上有两个数字,分别表示物品的总数和总价,有两个按钮,一个按了一下后,物品总数会增加11,并且在单价不变的情况下同时更新总价,而屏幕上显示的仅仅是真实总价的整数部分(但总价的实际值仍被保存),而另一个按了一下后,总价的实际值会增加11,总数保持不变。对于一组数据的x,yx,y,求要从屏幕上显示1,11,1(总价的实际值也为11)到屏幕上显示x,yx,y最少要按几次按钮。
做法: 本题需要用到贪心。
首先我们发现,按第一个按钮时单价不变,按第二个按钮是单价增加,因此单价是不降的,而目标单价ss的范围是:yx1s<y+1x1\frac{y}{x-1}\le s<\frac{y+1}{x-1}。接着我们发现,因为x10x\le 10,并且只有按第一个按钮一次时总数增加11,因此第一个按钮按的次数已经确认是x1x-1了,那么要求总按键数最小就等于求按第二个键的次数最小。我们发现当总数越大时,按第二个键所增加的单价1num\frac{1}{num}就越小,就越难达到目标的范围,因此我们发现,越早按第二个键越好。而因为单价有上限,所以我们只需枚举总数numnum,求总数从numnumnum+1num+1时,第二个键最多能按多少次,这个能很轻易地用式子O(1)O(1)算出。这样我们就解决了这一题。

【HDU5881】Tea-找规律
测试地址:Tea
题目大意: 有一个茶壶,无法得知里面茶的具体量,只知道在一个区间[L,R][L,R]中。要往两个杯子中倒茶(可以精确控制),使得两个杯子中茶的量之差的绝对值不超过11,茶壶中可以剩下不超过11的量的茶(你可以理解为,虽然你不知道茶的具体量,但是你能感觉到还剩下11),求倒茶次数的最小值。
做法: 本题需要用到找规律。
详细的策略看这里

【BZOJ3142】数列(HNOI2013)-组合数学
测试地址:数列
做法: 本题需要用到组合数学。
这题妙啊…但感觉真的不难…为什么我就是想不到呢…
这题要求满足下列条件的序列数:长度为kk,每个元素为11 ~ nn,差分序列中每个元素为11 ~ mm。对于每一个不同的差分序列ss,它对答案的的贡献是ni=1k1skn-\sum_{i=1}^{k-1}s_k,于是累加所有不同差分序列的贡献就是答案:
ans=nmk1d=1mk1i=1k1sd,ians=n\cdot m^{k-1}-\sum_{d=1}^{m^{k-1}}\sum_{i=1}^{k-1}s_{d,i}
因为m(k1)<nm(k-1)<n,所以所有差分序列都有可能出现,接下来我们发现,11 ~ mm中每个元素在所有不同差分序列中出现的次数是相等的,所以每个元素都出现了mk1km=mk2k\frac{m^{k-1}\cdot k}{m}=m^{k-2}\cdot k次,于是:
ans=nmk1mk2ki=1mians=n\cdot m^{k-1}-m^{k-2}\cdot k\cdot \sum_{i=1}^mi
所以最后:
ans=nmk1mk2km(m+1)2ans=n\cdot m^{k-1}-m^{k-2}\cdot k\cdot \frac{m(m+1)}{2}
用快速幂计算即可,时间复杂度O(logk)O(\log k)

【BZOJ3574】抄卡组(HNOI2014)-字符串哈希
测试地址:抄卡组
做法: 本题需要用到字符串哈希。
看到那诡异的大的数据范围,基本上确定数组都开不下了,所以要开vector…
然后输入貌似异常毒瘤,这也是我决定不写这道题的原因。
首先我们思考,如果所有字符串都不包含通配符,显然只要字符串哈希后,把哈希值排个序两两比对一下即可。
接下来,如果所有字符串都包含通配符,因为通配符可以匹配任何字符串,因此我们只要看,这些字符串的前缀(这里指字符串最前面的通配符之前的部分,后缀类似)和后缀满不满足一些性质就行了。观察发现,我们把字符串按前缀的长度从小到大排序,那么当且仅当前面的前缀是后面前缀的前缀子串时合法,后缀也一样。还是用字符串哈希匹配即可。
最后是部分字符串包含通配符的情况。首先把不含通配符的字符串进行哈希值比对,如果这些字符串内都出现不同就肯定没希望了,否则我们能得到最后所有字符串应该成为的样子,接着对于每个带通配符的字符串,这个字符串被通配符切割成若干段,我们需要在最终字符串中,从前到后依次匹配出这些连续段,能匹配得出来才是合法的。显然从前往后贪心匹配,同样用字符串哈希即可。
于是这个问题就解决了…不过据说还要进行卡时间等玄幻操作,本人实在是肝不动啊…

posted @ 2018-06-20 19:38  Maxwei_wzj  阅读(154)  评论(0编辑  收藏  举报