前言
话说第一个板刷计划由于种种原因而告一段落了。。其实那一版还有很多题想做,那就只能放一放了
附上效果图一张(几乎每一题都在我博客有题解):
打算
可以复习,重做自己做过的题,不局限于没做过的
乱刷计划
3223: Tyvj 1729 文艺平衡树
这题的话是一个Splay的裸题
并且只需要支持翻转操作
至于怎么找到区间,你就找到第l-1个,和第r+1个
把前者作为根,后者作为他的右儿子,那么跟的右儿子的左儿子就是所要的区间了
然后如果有翻转操作,在Splay之前,要把翻转标记下放
但由于我太久没有打Splay,然后还是做了很久。。
2458: [BeiJing2011]最小三角形
这题的话其实和最近公共点对是差不多的。。
都是左右儿子,然后约束分治
然后,还要用到三角形两边之和大于第三边就可以过了
1208: [HNOI2004]宠物收养所
这题的话也是一个splay的模板题
你可以一个splay两用,记录一下当前是谁多就可以了
但是我的splay巨慢。。bzoj过了,codevsT了。。
下午的时候发现我写成半单旋了(就是有一半的情况都是单旋的),怪不得这么慢
3679: 数字之积
这题的话,是一个非常简单的数位DP吧。。
考虑到每个数,都是类似于
2a∗3b∗5c∗7d
的形式
然后通过计算可以发现,指数是下表的时候,就已经超过
109
了:
2:30 3:19 5:13 7:11
所以指数不会超过这么多
于是设计状态f[i][a][b][c][d][e][f]表示还有多少位,每个指数是什么,是否还有限制,是否出现非0位就可以过了
1507: [NOI2003]Editor
直接Splay,今天刷了很多Splay了
然后奇怪的是,我在洛谷上0分,然后在bzoj就A了QAQ
我查错查了很久,最后交去bzoj,就A了。。那就当我A了吧
5132: [CodePlus2017年12月]火锅盛宴
上周做的了。。来凑凑数
我们可以对所有操作开一个优先队列
第一关键字是他熟的时间,第二是类型
然后当前的时间到达熟的时间时,就把他丢下去
然后对于每种食物开一个set,用来处理一些没有熟的
熟了之后就删掉
最后对于食物开一个线段树,维护有多少个就可以了
特别好写
3503: [Cqoi2014]和谐矩阵
这题的话
(nm)3
相信大家都会把。。
就直接暴力搞就好了
但明显地,这题是过不去的。。
但其实我们发现,如果第一行确定了,他后面都是可以确定的
c[i][j]=c[i−1][j] ^ c[i−1][j−1] ^ c[i−1][j+1] ^ c[i−2][j]
所以我们只需要搞第一行就可以了
但是方程怎么列呢?
我们可以处理出第
n+1
行是由什么异或而成,让他们都是0,那么方程就列出来了
3196: Tyvj 1730 二逼平衡树
人生第一道树套树了吧。。
我写的是线段树套主席树,
时间的话,只有3操作是
(nlog3n)
的,其他都是
(nlog2n)
但不管了,反正能过
空间的话是
(nlogn)
的,splay动态开点,线段树一直都在
听说可以写成线段树套线段树,虽然时间是稳定两个log的,但是空间似乎有点难受,于是就写了主流写法。。虽然应该可以被卡掉
2660: [Beijing wc2012]最多的方案
感觉是一个很好的题,一开始只想到可行的斐波那契不会很多
然后后面就不会
其实我们对于斐波那契,可以看成是一个二进制
然后你每一个就可以分解成他的后两个
不如说7,就是
1000000–>0110000–>0101100–>0101011
然后就知道一个斐波那契数有多少分解方式了
其实就是他是第几个斐波那契数减1再除2
然后我们先把n分解成最少的斐波那契数相加,那么问题就转化为分解这些斐波那契数有多少种方案
然后就DP啊,f[i][j]表示前i个斐波那契数,第i个斐波那契是由自己构成还是由别人合成的,有多少种构成方案,就可以了
3226: [Sdoi2008]校门外的区间
蛮简单的一道题,只要想的时候思路不乱就可以了
于是我就在睡觉的时候想这题的细节。。
设一个点在几何内为
true
,不在为
false
翻译一下语言,用线段树维护就可以了
U:把一段区间变成
true
I:把一段区间以外变成
false
D:把一段区间变成
false
C:吧一段区间以外的变成
false
,然后区间内取反
S:直接区间内取反
1875: [SDOI2009]HH去散步
这题的话,你按照边来设计状态
表示到达这条边有多少种方案
然后有公共点的就可以转移
一开始与a点相连的有1,最后统计与b点相连的
然后矩阵快速幂一下就可以了
4299: Codechef FRBSUM
这题是一个挺好的题
首先我们考虑到,如果我们当前已经可以拼凑出x,那么如果我们加入一个
≤x+1
的数i,那么他就可以范围变成
x+i
这么大
然后我们考虑,如果我们当前的和为i,就寻找
≤i+1
的和,如果比当前的值大,那么就更新,否则就退出
这个的话自己想一想就知道为什么了
然后的话,这个过程,那个值至少会大一倍,所以是log级别的,寻找和是log的,然后就可以
(Qlog2n)
过了这道题了
3591: 最长上升子序列
还是一个很好的一道题啊。。垃圾的我完全没有想到。。
由于是最长上升子序列,所以我们考虑原问题的做法。就是维护一个a[i]表示长度为i,最后一位的最小值。对吧,然后这个是单调的,所以可以二分查询,更新。
那么我们依然考虑模拟维护这个过程
我们设状态f[i][k]表示当前有哪些数已经进到数列里面了,有哪些还在a数组里面。
我们每一次就考虑将一个新的数放到里面,然后类似地,我们寻找第一个比他大的,然后把值替换就可以完成维护操作了。
我们可以先预处理一个数组
g[i][j]
,表示当前栈的状态为i,然后现在加入了一个j,状态会变成什么
考虑DP
f[i]
,
i
是一个三进制数,
状压DP一下
每次就枚举一下那些在数列里面了,然后枚举子集,也就是当前哪些还在a数组里面,然后DP一下就可以了
注意,要尽量剪枝。。这题只有2s
代码
3862: Little Devil I
这题的话,很久之前就想做了。。
然后如果你像我一样没有权限号,可以去hdu交
现在才填。。
首先,1和3操作都是很常规的
问题就是2操作怎么弄??
我们不妨这么考虑,我们给点也上色,每一条边,真正的颜色是他异或上他两边的节点
对于一个2操作,我们就把路径上所有点的颜色取反,就好了。有一个要注意的是,如果要修改的
(x,y)
这条路径,如果他是在一条路径上,那么要把他们重链上相邻的两条边也取反
然后呢,我们对于询问,重链上的是维护好的,对于轻链上的边,就暴力找到他两端节点的颜色,异或起来就好了
然后由于每个点最多只会经过log条重链,所以时间复杂度还是
O(nlog2n)
的
1008: [HNOI2008]越狱
这题以前做过了,今天心血来潮,来复习了一下
一开始还想挫了。。想到了容斥。。
就是有一对相邻,两对如此类推
然后忽然发现,我们直接用
mn−m∗(m−1)n−1
不就可以了嘛。。
2152: 聪聪可可
以前做过的一个题了。。点分治入门题,由于太久没写过点分治,所以来复习一下
说一下点分吧:
1.寻找重心 2.计算包含重心的路径 3.递归做
然后就可以了,然后有时候情况算多了记得去重
2434: [Noi2011]阿狸的打字机
以前以为这题很难。。然后今天做的时候发现其实很简单。。
你就建一个AC自动机的fail树
问题就转换为问你一个子树里面有多少个节点是包含某个值的。
这个的话,你可以离线处理,按y值排个序。
然后对fail树建立dfs序,然后弄一弄就好了。。
没什么好说的。。1A了
4401: 块的计数
也是以前做过的一题了。。
我们考虑到,如果块的大小固定了,分发也就只有一个
于是我们可以DP判断可行
f[i]
表示以
i
为根,分完之后还剩多少个
最后的话,如果
然后我们考虑到,一个子树如果被删掉了,
f[i]=size
的时候,也就是说他的所有儿子都被分出去之后,他剩下size个
换句话说,如果想不留给上面,那么他子树的个数必须是size的倍数
然后,我们可以统计一下整棵树里面,儿子个数是size的整数倍的有多少个
如果是
n/size
这么多,就是合法的,正确性显然。。
1941: [Sdoi2010]Hide and Seek
这题的话呢,算是我KD-tree的第一题了吧。。
感觉还是很暴力的。。
主流应该是按照方差分开,但我还是写了一个比较简单的x和y轮着来
然后在寻找时,也是很暴力地找。。大概估计一下里面有没有可能有最优解,没有就不去了
但是期望似乎是
logn
的,最差似乎也是
n−−√
的,但是我似乎还不是很会证明他的复杂度。。就先这样吧。。
4066: 简单题
这题的话,如果不是离线,就是CDQ分治的经典题目了。。
但是这题要强制在线,但是我以前都不会。。
现在的话,就可以用KD-tree来做了
和上一题差不多的
然后对于每一个矩阵,也就是kd-tree上的节点,还要记录一个和
然后在查询的时候,如果询问的和当前是包含关系,就直接全部加上。如果是分离,就不查询。否则递归。
插入就暴力插入,到达一定次数就把整颗树重构一次。
然后就可以通过这题了
但是KD-tree的最差根号复杂度我还是不会证。。
2648: SJY摆棋子
直接KD-tree上就可以了。。
虽然感觉时间有点炸。。
但是题面上面叫我用KD-tree,那我就试了一下。。发现还真的可以过诶
然后加了一个次数多就重构就T了。。可能是我重构的姿势不对,等我有空弄一弄替罪羊式重构再来填这个坑
update:
下午校庆,去玩了。。
然后学会了替罪羊的正确姿势
大概就是你看一下子树,如果两个儿子差别太多了,这个的话是用一个儿子与总节点个数比较,如果占到75%了,也就是不平衡了,那么我们就把子树重构一下。感觉蛮好写。。但是“简单题”跑得比定时重构要慢一点点。但听说复杂度均摊是
logn
的,因为重构次数不多?
5122: [Lydsy12月赛]彩虹溜冰鞋
详细内容在这里+
5123:[Lydsy12月赛]线段树的匹配
这题的话,容易发现,如果一个区间L,R,区间跨度(R-L+1)是一样的话,那么答案就是一样的
所以我们直接设计状态
f[i][j]
表示区间跨度为i,这个节点选了没,然后转移就可以了
然后因为线段树上面,区间跨度只有log个。。所以做一个类似树形DP的就可以通过了
5128:[Lydsy12月赛]寻找母串
这题的话,考虑到T只有200,于是我们可以爆搜
我们就枚举长度,这个必须是长度的因数
然后再枚举子串
要注意的是,这里有一个十分强力的剪枝,就是说,如果这个串变多若干次后,如果字符个数不一样,就一定是不合法的。这一个剪枝可以减去大部分不合法的情况。如果不加,会慢到飞起。。
然后我们可以用一个DP判定
f[i][j]
表示,
i
到
然后注意一下那个重要的剪枝就可以过了
5127 [Lydsy12月赛]数据校验
容易发现,一个符合要求的区间,一定是一个两两之间差值不超过1的
然后随便做做就好了
月赛最水一题。。
5125: [Lydsy12月赛]小Q的书架
详细内容在这里
1018: [SHOI2008]堵塞的交通traffic
这题话,还是一个不难的题吧。。
感觉主要就是分类讨论有点多,因此写起来很烦。。并且很容易错。。如果你精神不好就不要做了
定义一个矩阵里面的四个点
如果我们有办法去除以给出的两个端点的矩阵四个点的连通性,答案就出来了
于是我们可以用线段树维护一段区间的以下值:
U:第一行mid,mid+1两列之间是否联通
D:第二行mid,mid+1两列之间是否联通
l:s1,s3是否联通
r:s2,s4是否联通
u:s1,s2是否联通
d:s3,s4是否联通
q:s1,s4是否联通
p:s3,s2是否联通
大力分类讨论转移即可
4424: Cf19E Fairy
以前的陈题了
我们考虑到,如果是二分图,一定没有奇环
于是我们考虑,如果是奇环上的边,就一定要删掉
但是我们会发现一个新的问题,就是如果这条边在一个偶环上,那么他又会产生一个新的奇环
于是问题就变为了,所有奇环的交,且不再偶环上的是那些边
建立生成树,乱搞一下就好了
2539: [Ctsc2000]丘比特的烦恼
很明显的一个二分图最大权匹配
但似乎坑点很多(题面的锅),看看题目dis就好了。。
费用流可过,不用写KM
1057: [ZJOI2007]棋盘制作
以前做过的一道题了。。以前一直觉得很难,然后今天看回来,也不过如此
我们定义,(i,j)对应的悬线是他一直向上走,知道遇到一个障碍点
明显地,一个最大的子矩阵一定对应一条悬线
于是我们枚举悬线,DP一下每一条悬线左右两端扩展的最远,和上面扩展最远就可以了
由于悬线个数是
nm
的,因此时间也是
nm
的
2461: [BeiJing2011]符环
这题的话,考虑爆搜。。
但是爆搜是
250
的,明显过不去
考虑记忆化
在什么相同的情况下,答案会一样呢?
明显地,当前左边没匹配完的
(
算一个吧,那么左边就没有了,因为右括号和左括号抵消就好了,因为他不可以比左括号多啊
然后右边要有什么呢?
肯定要有一个有多少个右括号没有匹配啊,但是似乎不够,那么就再来一个有多少个左括号没有匹配
然后状态就出来了
1797: [Ahoi2009]Mincut 最小割
由于某些原因。。故意复习了一下这道题
主要的话是有三个结论就可以做了
1.对于一条边,要是有一种割集包含他的话,那么他肯定是满流的。但如果他是漫流的,不一定有一个割集包含他。
2.如果一条边的两端x和y,在残余网络中属于同一个连通分量,那么也没有一个割集包含他
3.满流的桥是一定要割的
3532: [Sdoi2014]Lis
这题的话,还是很棒的一道题吧
首先,如果只有第一问还是很好弄的
你就随便DP一下,就出以他结尾的
然后如果存在有
f[i]=f[j]+1
且
a[i]>a[j]
且
i>j
那么就用j向i连边,就可以了
但是第二问就不好弄了
从上一题我们知道,如果他是满流的,且两个端点属于同一个连通分量。但是我们嫌麻烦,并不想写强连通。那么我们发现,他是满流的,说明他的反向边是有流量的,那么如果存在一条路径使得x可以走到y,那么就是联通了。所以就判一下连通性就好了
然后如果他可以在割集里面,我们就把它割掉
怎么割呢?
就是退流,把st–>x这条路径的流量还回来,把y–>ed还回去就可以了
这个可以用x走回st来实现
然后我们就按c从小到大,贪心来弄就好了
2597: [Wc2007]剪刀石头布
太久没做过费用流,连最基本的差分都忘了
一个图,他符合要求的三元组有多少个呢?
不难发现,一个不符合的三元组,一定是一个点拥有的两条出边
进一步想,一个不符合的三元组,一定对应同一个点的两条出边,而同一个点的两条出边,一定对应一个不符合的三元组
于是答案怎么算就出来了,就是
(n3)−∑ni=1(d[i]2)
其中d[i]为一个点出度
我们考虑让他最小,就是让后面的点最小
然后考虑建图
对于每一场比赛
i
,都有
但是这个方法似乎并不是特别优秀,因为看起来很慢。。快的人一下就过了
3131: [Sdoi2013]淘金
很简单的一道题吧。。
和之前一题差不多,考虑到肯定是有2,3,5,7构成的,然而2,3,5,7的幂到达下表是就爆1e12了
2:40 3:26 5:18 7:15
于是又可以设计一个和之前一样的状态来跑。。
然后我们猜想,最后能变出来的不多,事实也是如此,你先打一个劣质的数位DP,就会发现,能变出来的只有8000+个,不到1w个。那就可以用一个数位DP吧变出
2460: [BeiJing2011]元素
太久没有搞线性基了,感觉快忘光了,赶紧来复习一下,以前觉得线性基很难,但现在看来,也不过如此,其实在想通高斯消元解异或方程组就没什么难的了。
其实线性基就是原数集的一个压缩,里面的数通过异或可以得到原数集的任意一个数。
然后支持插入一个数,合并,寻找异或最大,第k大等等
第k大的操作其实很简单,我们先把每一位独立,就是如果第
i
为上的数
这题就贪心地先把大的放进去,然后看看是否之前存在,就可以了。。
2115: [Wc2011] Xor
这题的话,考虑到他是双向边,和异或的性质:一个数被异或两次就会被清0
所以其实,我们如果想随便跑出一条路,然后能产生新的贡献的,就肯定是环上面的边了。因为你走别的,以后都肯定要原路走回来,这样就相当于没有了,但是环你可以不原路返回。那么问题就是你现在可以异或一个环的值,要你值最大,这个的话,如果知道所有环的值,那么用一个线性基就可以维护了
然后考虑怎么找环,我们可以先一开始建一个生成树,然后往里面加边,加入一条边,就看看他产生的环的代价。同时,不需要考虑加入两条边所产生的环,因为他们可以被别人构出来。
虽然步骤好像很长,又要产生路径,又要生成树,但其实两个都是可以用一个dfs来解决的。。
1999: [Noip2007]Core树网的核
这题的话,如果他不告诉你要在直径上,那么还是在直径上的。。所以这个条件其实是没什么用的。。
然后其实就和之前有道消防站的建设是差不多的。。
就算随便弄出一个直径,然后在直径上面扫一遍就可以了
然后每次加点和删点就维护一下每个点到直径的最大值就好了
1014: [JSOI2008]火星人prefix
自合体的话就是用splay来维护一下hash就好了
一开始每个节点想维护
1 i
的hahs值,发现,插入不好搞
于是转换思路,维护一个子树的hash值,这样就好了
然后一开始人工取模,一直T。。改了自然溢出才过
1951: [Sdoi2010]古代猪文
我的数学好菜啊。。怎么搞都不会
考虑到费马小定理
a(p−1)(modp)=1
所以我们的指数是可以对
(p−1)
取膜的
然后发现,
(p−1)
不是质数,不能Lucas,并且组合数很大
于是我们考虑对
(p−1)
分解质因数,最后再用中国剩余定理合并
然后就好了。。
中国剩余定理全忘了。。看来当时学得不扎实,重新学了一次。。
4867: [Ynoi2017]舌尖上的由乃
这题的话,直接dfs序,然后分块就好了。。
一直保持块内有序,有加操作,就归并重构
块的大小取
n−−√logn
2726: [SDOI2012]任务安排
详细内容点这里
1492: [NOI2007]货币兑换Cash
这题的话,其实核心内容和上一题是差不多的。。
但是DP比较烦
因为式子特别长。。
一开始吧他大力展开了,发现瞬间爆炸。。
还是把手头上A和B股票的最多看成一个点,然后到时候就相当与知道点和和斜率
然后CDQ分治DP就好了
2324: [ZJOI2011]营救皮卡丘
很好的一道题啊。。
构图方式要学习,还有用floyd来完成限制
在floyd,只有转折点比其中其中一个小的时候,才可以进行转移
这样就可以完美地觉得一定要走完
k−1
这个限制了
然后建图的话,就用类似于最短路径覆盖的方式来搞就好了
4866: [Ynoi2017]由乃的商场之旅
很棒的一道题啊!
话说今天下午突发奇想,去找了一下由乃,就找到这道题了。
不难发现,当一个子串经过排列可以变成一个回文,他的字母每个种类的个数肯定都是偶数,至多有一个奇数
这就是我们想起了异或,每个数分配一个权值,,就是
2i
,然后异或起来,如果最后得到的只有一个或者0,就是合法的
花了下午做了一个
26nn−−√
的做法,就是直接莫队,维护一个
226
的桶,表示每种后缀有多少个。然后我们在移动端点的时候,后缀的话,就打一个lazy异或标记。前缀的话,就用后缀异或整段的和,就得到所有前缀,然后胡乱搞一搞就可以了
事实证明,这样是过不去的。。于是又话了一个晚上学了一个新的做法,时间是
n26n−−−√
的
做法大概是这样的
对于每个点,预处理它到所在的块的右端点的答案。莫队的时候从右端点开始扩展。最后,枚举左边那个不完整的部分统计答案即可。
然后块的大小取
26n−−−√
这样为什么会快呢?因为他右端点,移动一个的代价还是
26
的,但是他移动的次数变少了。然而左端点移动次数虽然变多了,但是代价变成
O(1)
,两边平衡了复杂度,因而有了很大的优化
4811: [Ynoi2017]由乃的OJ
搞了一个上午才做完这个题
首先,按位考虑是十分明显的吧。。因为这三个运算位与位之前互不影响啊
然后一个
O(knlog2n)
的做法就十分明显了
就是你就从高位往低位贪心,查一查这一位填0会变成什么,填0会变成什么,然后树剖查询。这个怎么查询,也是很简单的。你就在线段树上面维护每一个点填1变成什么,填0变成什么,然后随便合并一下就好了。。但是这个有个问题,就是每一位都要查询,这样就很慢
然后我们考虑,有没有不需要每一位都查询,能不能用
O(nlog2n)
的时间查询,然后k个位
O(1)
来搞
我们考虑到,如果我们知道,
111.....111
和
000...000
丢进去是什么,那么我们就可以知道每一位填1和填0是什么了,对吧
然后我们考虑怎么维护这个东西
就以
000...000
为栗子吧
首先,我们想知道的肯定是那些为可以变成1
明显地,当他被丢到左儿子的时候,会变成一个新的状态,我们设他为
a
那么
如果第
那么就可以推出这个式子了
c.x0=(a.x0&b.x1)|(~a.x0&b.x0)
然后就可以完成维护了
然后还有一个细节要注意,就是先后顺序的问题,这个的话,是不可以随便交换顺序的,你在树剖查询的时候注意一下就好了
3738: [Ontak2013]Kapitał
话说好久没写过扩展Lucas。。都忘了,赶紧来复习一下QAQ
就直接扩展lucas,先求出膜
然后对于去掉末尾的0,就在最后乘上多余系数的时候消掉少的那个就可以了
3129: [Sdoi2013]方程
很简单的一个容斥原理吧。。
明显地,后面那个限制,直接用m减掉,就跟没有一样了。。
那么就剩下
n1
个限制,这个的话,直接容斥一下就可以了
考虑到组合数很大,膜数也很大,因此使用扩展Lucas即可
出题人不会卡你的
4520: [Cqoi2016]K远点对
KD-tree又来优化大暴力了
其实欧式距离和之前曼哈顿的打法是一模一样的
就直接kd-tree就可以了,跑得飞快
然后你就储存一下当前的k大,这个过程可以用一个堆来维护
4763: 雪辉 & 4812: [Ynoi2017]由乃打扑克
没想到我的第一个50题计划,以两个都差不多,都是很假的题结束了QAQ
感觉这两题的做法都很假啊,感觉他如果加上一个条件,就是询问个数不超过某个数,那么就没怎么假了23333
怎么做呢?
考虑我们选择
n−−√
的点作为“有色点”
有色点的选择有个特点,就是树上所有的点,到他父亲最近的有色点距离不超过
n−−√
然后我们就可以预处理信息了啊,对于每个有色点,预处理
f[i][j]
,表示
i
好有色点到他祖先有色点
然后你每一次,对于x和y节点,就暴力往上跳,直到跳到了一个”有色点”,就开始跳有色点,跳到距离LCA最近的时候,就继续暴力跳
这样的话,你每一次就最多跳
n−−√
步,到达j,就可以直接取出
f[i][j]
,这里是
n/64
的,然后你暴力跳的时候是暴力修改,是
O(1)
D1,所以一个询问是
n−−√+n/64
的。。
感觉跑不过的。。空间很大,时间理论复杂度也蛮大的。。
然后对于询问,就暴力查询bitset,这个的话就需要你手写一个bitset了,这样就可以完成两题的要求了
感觉这两题都很假