题表

这里写图片描述

mark

关于一个数学工具:https://blog.bill.moe/yaliD7T1-conjugate/

待完成

字符串
BZOJ4554
Codeforces666E
数学
BZOJ1129
数据结构
BZOJ4358

贪心

[HDU6000]Wash
题意:有L件衣服要洗(不超过1000000 真的多)。有N个洗衣机和M个烘干机,然而它们都太小了,因此一次只能处理一件衣服。
第i个洗衣机洗一件衣服需要a[i]时间,第i个烘干衣服需要b[i]时间,询问搞完所有衣服最少要多少时间。一件衣服可以洗完之后等一会再烘干,不计算中间任何其余过程的时间(把衣服放进洗衣机这种)

首先,如果只洗衣服,那么显然贪心就好了。假设第i次从堆里取出时间最少的那个< id , t >,那么ans_w[i] = t,然后再把< id , t+a[i] >放进堆就可以了
然而再加上烘干呢?因为是有先后顺序的,正着贪心不好做,于是倒着贪心。给最后一件洗完的衣服配上最短时间的烘干机;倒数第二件洗完的,配上时间次短的烘干机(或者是时间最短的烘干机的两倍,相当于是这一件用完了,下一件接着用)。 所以只要对烘干也求一个像上面那样的ans_f数组,然后最终答案就是max( ans_w [i]+ans_f [L-i+1])

数据结构

树状数组

[Codeforces 869E]
题意:在一个m×n的方格板上,操作1将一个矩形区域的边界上加上一圈障碍,操作2将一个矩形区域的边界上的障碍移除,操作3询问两点是否能不越过障碍互相到达。
对于每个加障碍的操作,都随便rand一个值给它加上去,查询的时候直接查两个点的值是否相等即可。移除障碍就把rand的值减掉

分块

[BZOJ4765] 普通计算姬
对答案以及dfs序前缀和用分块。处理出每个位置对于答案块的贡献。修改时,对于答案,只有整块才修改,delta乘上系数即可,对于dfs序前缀和,根号修改即可。询问如果是整块,则直接调用块的答案。对于零散部分,对于每个暴力在dfs序前缀和分块里查询,单个查询差分O(1),总复杂度根号。

线段树

[SPOJ GSS2]
https://oi.abcdabcd987.com/gss2/
这道题非常的有意思,它查询区间和,但是还不计重复。说实话,看到不计重复这种诡异的条件,往可持久化想了,然后完全就没了思路。Orz 网上各种题解。这题有一个比较仁慈的地方:没有修改操作!所以可以离线。
按照右端点排序询问。我们令s[i]为不重复的sum[i..x],其中x在最外层循环中从1~n。x每前进一位,把s[last[x]+1]到s[x]全部加上a[x],其中last[x]是x上一次出现的位置。现在,当x等于某一个询问的右端点r的时候,我们的询问[l, r],相当于询问所有历史中(包括现在)出现的最大的s[k] (k <= r)。听到历史这个词,很容易想到可持久化数据结构,或者说二维数据结构(比如套一个时间维)。但是实际上,这题要求的历史,是从一开始的历史,而不是从某个时间点开始的,因此,还是可以直接使用线段树的。
[BZOJ2962]序列操作
其实是比较沙比的一道题,暴力维护sum[20]即可。对于第一种修改,sum[c] = sigma(ls.sum[i] * rs.sum[c – i]) i = 0 ~ c。对于第二种修改,奇次方取反即可。pushdown的时候如果两个flag同时存在,先push取反,然后把儿子的add也取反,然后再push add。Modify的时候如果先有add后来push,则add需要取反

可并堆

[BZOJ4003] [JLOI2015]城池攻占
带标记的可并堆
或者用三进制倍增 https://blog.csdn.net/u014609452/article/details/51286317
[BZOJ4585][Apio2016]烟火表演
树dp,维护两个数组f[u][i]和g[u][i],表示把u子树内的叶子到自己的距离全部搞成i的最小代价,g表示和自己父亲的距离全部搞成i的最小代价。对于叶子,把g第二维拿出来画一个图像,发现它是上凸的,然后合并到父亲的f还是一个上凸的。关于由父亲的f求出g,可以发现最后还是一个上凸的,于是用可并堆维护凸包,相当于维护了这个数组,来做dp。

动态点分治

[BZOJ3924] [ZJOI2015]幻想乡战略游戏

树链剖分

[BZOJ3924] [ZJOI2015]幻想乡战略游戏
[BZOJ2325] [ZJOI2011]道馆之战
简单树链剖分维护连通性,维护从左下/左上 到 右下/右上是否可行,以及可行的最大步数,还有从左上/左下/右上/右下 出发,最多走的步数,合并信息即可


字符串

[BZOJ4017] || [TJOI2017]异或和
第一问随便统计一下就好了(枚举位,枚举结束位置,统计0和1的个数,然后根据前缀异或和的奇偶型计算就好了)
关于第二问,先把前缀和序列搞出来,然后现在就是要求 任意两数之差 的异或和 的和
还是分位考虑贡献,对于第i位,将所有数字取模1<<(i+1)之后答案不变。然后将一个数组排序,枚举另一个数字,用加起来的和为01…的减去00…的,11…的减去10…的(可以用lower_bound),得到的答案就是该位为1的方案数,最后看奇偶性累加进答案。

任意两数和的异或和代码:
这里写图片描述

2016-2017 ACM-ICPC (NEERC 16)
题意:给出N个二进制编码(每个编码都是一个01串),串总长不超过500000。有一些串中间可能出现’?’字符,’?’的位置要么是0,要么是1,且一个串最多出现一个’?’。现在询问这个编码是否可能合法,如果合法,输出任意一种方案。合法:任意一个编码不是另一个编码的前缀

解法:首先比较显然的暴力,就是枚举两个串,如果这两个串除了问号位置,其余都相同(说明一个串是另一个串的前缀),所以这两个串的’?’位置是有冲突关系的,显然2-SAT
当然这样是 N2 的,考虑用trie来优化建边
对于每个串,将其问号取0/1都插入进trie树。那么显然trie上任意一条从根到叶子节点的链上,都只能存在一个end节点。于是前缀链,后缀链优化建边就好了。输出方案嘛,既然都知道每个节点的true or false,也就是很显然的东西了


数论

[UOJ300][CTSC2017]吉夫特
卢卡斯+(分块优化dp 或者 子集dp)

[洛谷P3790]文艺数学题
题意:询问所有生成树边权gcd的和
用f(i)表示边权gcd为i的树的个数。用F(i)表示边权gcd为i的倍数的个数。
F(i)可以用矩阵树定理(就是「度数矩阵-邻接负一矩阵」的n-1阶余子式)来求。然后经典容斥。但是这样会T掉。
所以判一下,只有当一个约数出现次数大于等于n-1时,才去跑行列式,于是可过。官方题解

[Codeforces 360D]Levko and Sets
原根+卢卡斯+各种性质的神题,yyf的题解

[HDU4372]Count the Buildings
对问题转化到环排列,进而到第一类斯特林数,dp预处理后O(1)回答询问(其实也可以直接定义dp[i][j]表示i个里能看见j个,只考虑左半边,从大到小插入,除了插入在最左边可以看见,其他地方都看不见,即dp[i+1][j] = dp[i][j]*i + dp[i][j-1],然后与正解类似)

[BZOJ5093]图的价值
题意:带标号的图,价值定义为每个点度数的k次方的和。计算所有n个点的简单无向图的价值之和
发现每个点的贡献独立,于是对于每个点考虑贡献,最后乘上n即可
对于一个点,枚举度数,组合数它和哪些相连,其余的边有没有2^其余边数。度数的k次方化成斯特林数的式子,之后把斯特林数拆成阶乘的那个式子,然后用NTT即可。类似方法还有:[BZOJ4555][Tjoi2016&Heoi2016]求和

[BZOJ3462]DZY Loves Math II
对于一个2e6的S,拆成若干个质数(并且不能有质数的多次方因子,否则仅凭lcm质数无法凑出S),那么最多只有7个素数(2,3,5,7,11,13,17乘积500000,再多一个超过2e6)。那么原题相当于是只有7个物品的背包方案数。然而n太大了,发现S是所有物品的倍数,于是如果一个物品选了a个,占用体积 ap ,体积可以拆分成 bS+cp (c小于S/p),那么原题转化成「体积小于7S的背包+大块的S分配给7组」的方案数。枚举零散的部分 kS+n%S ,每个物品有使用次数上限,( dp[i][j]=dp[i1][(jp)(j2p)...jlimp] ,开一个数组sum[0~p-1],然后转移直接从数组里拿,注意减去超出lim的贡献即可)。对于大块的S分配,相当于无编号球放进有编号盒子里,夹棍法即可。

[BZOJ4870][SHOI2017]组合数问题
看上去是组合数推式子,实际上是dp
相当于是要选一些东西,使得最后选的东西个数取模K剩余r,于是根据当前物品选和不选写出dp式子,然后矩阵乘法转移即可。
还有一种,直接对dp数组作类似快速幂的东西,复杂度可以少一个K


图论

某NOIP模拟
题意:给出一个无向图,要求给这个图定向使之成为一个DAG,使得最长路最短,点数小于等于17,边权都是1
对一个已经定向的图跑一个拓扑dp,dp保存最长路的路径长度,那么相同dp值相同的一定是一个独立集。所以dp最少多少个独立集可以覆盖完整个图,枚举子集即可。

[BZOJ3832][Poi2014]Rally
DAG的最短路可以这么看:求出f[u],g[u]表示到u的最长路和u能走到的最长路
然后再新建超级源点S和T,S向所有入度为0的连边,出度为0的向T连边,原图的每条边权定义为f[u]+g[v]+1,那么原图的最长路对应新图任意一个割集的最大值。于是可以枚举删掉某个点之后的割集。PoPoQQQ的题解:。那么如何才能做到,删除一个点之后,立刻获得某个割集的最大值呢?可以根据拓扑序来删点,删除进入点i的和g[i],加上从i出去的和f[i],这样让每条路径总是和下一层的点有关,而已经被枚举过的不会再被删。

[BZOJ3073][Pa2011]Journeys
线段树优化建边最短路

[POJ2175]
题意:给出一个已经跑好的费用流,问是否是最优方案,若不是最优则输出任意一种最优方案
如果不是最优的话,残量网络中一定存在负权环(退流费用大的,增流费用小的,显然费用和为负),所以搞出负权环之后退一圈的流就好了。

[BZOJ4289][PA2012]Tax
这道题的路径长度十分奇怪,经过的点由权值,并且权值还是进入边和离去边的边权取max
那么最基本的,可以想到把每条无向边看作两条有向边,然后把有向边看作一个点。对于原图点u的一条入边点in和出边点out,加边in->out,边权为原两边权值较大值,然后跑最短路。然而这样做是不行的,因为一个菊花图就可以把新图的边数卡到 n2 。于是考虑优化,把出边按照边权排个序,小权值的向大权值的连一条边权为差值的边;大权值的向小权值的连接一条边权为0的边。然后把同一条边拆出来的 e e 连一条边权为原图边权的边。
这样的话,从一个入边点 e 走到一个出边点,再沿着差分边走,如果到了一个较大的出边,那么路径总长就是 e+Δ= ,同理,如果走到了一个较小的出边,那么路径总长就是 e+0= ,正好符合题意。
!!!!这个题的要点就是,差分优化建边,小的向大的补权。

[BZOJ2285][洛谷P2494][Sdoi2011]保密
这就是一个沙比糅合题,先用类似01分规的方式跑出对于那161个点的最短路,然后就是二分图带权匹配,费用流即可。

[BZOJ3597][Scoi2014]方伯伯运椰子
首先我们可以把图上的边权搞出来。如果是退流边,边权a-d,容量c,如果是增流边,边权b+d,容量inf。
然后可以发现,题里面说的 XYk ,分子就是边权和,分母就是边数,然后这就是一个经典01分规:寻找边权比边数最小的环(这道题里面边权是负的,所以比值也是负的)。要使 sumtot 最大,不妨设最小比值为 C ,那么满足 i:sumitotiC ,这个式子满足单调性,考虑二分求解。假设二分到了一个 Cnow ,设 sumtotC ,即 sumCtot0 ,把每条边的边权减去C之后,如果出现了负权环,说明 Cnow 小了(注意C是负的),否则大了.

[BZOJ1997][Hnoi2010]Planar
点才200个,但是边太多了,如果 n2 建2-SAT边的话肯定会炸。这时候需要用上一个性质(如果没有这个性质,这道题也不会出现在这里了)。即:平面图中,点数N边数最多3N-6。证明:欧拉定理:点+面-边=2,极大平面图中三条边围成一个面,一个边被两个面共享,即 3*面=2*边 ,于是带入可得 3*点-边=6。所以如果边太多直接输出NO即可,否则 N2 建边。

[BZOJ2709][Violet 1]迷宫花园
直接二分答案+最短路check
(二分性:首先那种横着步数比别人多,纵向步数还比别人多的方案肯定被排除掉。那么现在就剩下横向步数单增,纵向步数单减的这么一些路径。当v较小的时候,横向步数少纵向步数多的路径肯定优。随着v逐渐增大,最优的决策会纵向步数减少的方向移动,但是总体步数仍然单增。唯一一种不符合的情况就是:最短路根本不用经过纵向道路,然而数据保证不存在)

[BZOJ2707][SDOI2012]走迷宫
其实是个比较简单的期望题
首先注意到题目中所说的:如果到不了终点,则步数为INF。由于期望=权值*概率,因此只要有概率到不了终点,也就是T所在的SCC并不是唯一一个没有出度的SCC,那么答案INF。
剩下的就很好办了,逆拓扑序把缩点之后的图建出来,对于已经知道的E,直接带入常量,不然解高斯消元(题目里SCCsize不超过100的提示,简直不能太明显)。

[HDU3018]Ant Trip
对于每个连通块分别考虑,如果一个连通块中点的度数全部是偶数,则显然有欧拉回路,一笔。不然,一定有偶数个度数为奇数的点,每起笔一次就可以消灭且仅消灭一对度数为奇数的点,所以是:奇数点数/2 笔

[BZOJ2407]探险/[BZOJ4398]福慧双修
此题解法参见me的博客

[BZOJ4439][Swerc2015]Landscaping
其实题目说的很复杂…提炼出来就是,如果相邻块不同那么有A的花费,改变高度会花费B,询问最小花费。
我们可以将每个点拆开成两个,表示需要变低的点low和需要变高的点hig
显然对于每个点S->low,如果本来就是低点边权0(相当于不连),不然边权A。hig->T也是同理。
然后两列点之间,位置相邻的连边,表示冲突的花费。但是由于最后的状态是不知道的,一个点在变化之后,会与原来和它相同的点产生冲突,因此在两列点各自的内部,相邻的点连往返都为A的边。这样连完之后,发现两列点其实可以合成一列,因为内部连边一样,而两列之间一定是S->low->hig->T。
所以最后的建图就是:对于每个点i,如果原来是高的(S to i , B),如果原来是低的(i to T,B)。然后相邻的点i,j连(i to j,A)和(j to i,A)
与此建图相同的,在BZOJ上还有另外两道

[BZOJ3624]免费道路
首先贪心的考虑一下,假如在做最小生存树的时候,优先选黑边,可能会导致图不连通。因为可能有些块之间只有黑边才能相连,而优先选黑边的时候又已经选了K条黑边不能再选了,这时就无法连通。
那么先白边优先做一次最小生成树,处理出那些必要的黑边。然后把这些必要的黑边连上之后,再黑边优先做一次最小生成树。第二遍的时候,即使黑边优先,也只会替换掉第一次生成树中的白边,显然最后一定会形成树

[BZOJ2208][Jsoi2010]连通数
tarjan缩点+拓扑+bitset,很水的一道题

[洛谷P3403]跳楼机
思维被局限…emmm
最短路,不仅仅是图上的最短路,也可以用于组合形式
定义f[i]表示在取模x的意义下,用y和z最早在什么时候凑出来。如果到了这个高度,显然可以加任意多倍的x凑到f[i]+x,f[i]+2x等等,那么对于有值的f[i],贡献就是(h-f[i])/x+1。那么怎么求出这个f[i]呢,建图(i,(i+y)%x,y),(i,(i+z)%x,z),跑最短路即可。

[BZOJ5201][NEERC2017]Connections
Claris太神啦!!!
考虑kosaraju的核心思路,在逆向图上dfs一遍,在return之前将当前点入栈,求出逆后续遍历。然后按照栈从顶向下的顺序,在正向图上dfs求出SCC,dfs多少遍就有多少个SCC。
为什么是正确的呢?在dfs一个连通图的反图的时候,栈里在i之下的,都是「能到达i」的点。而在正向图遍历的时候,如果i到达了一个点u,而u还没有被访问过,说明这就是一个环,i和u同属于一个SCC。因为i到u,在正向图和反向图中都有路径,那么这就是一个环。
这道题就用到了这个性质,因为保证整个图强连通,从1出发可以遍历到所有的点。而在反向图中从1出发,也可以遍历到所有的点。把正向遍历和反向遍历中1到i的两条路径拼接起来,就是一个强连通的了。我们把正反dfs的路径都保留,这样的路径不超过 2(N1) 条,符合题意。如果不够的话,随便凑几条边补上去就好了

[BZOJ3875][Ahoi2014&Jsoi2014]骑士游戏
解法1:用dijkstra找出当前最优的去更新距离,看me的博客
解法2:spfa更新带环dp

[BZOJ2597][Wc2007]剪刀石头布
如果正着做的话,是类似文理分科这样的模型的,就是把每条边看成点,然后如果都选1或者都选0就获得1的利益
然而这样建图,不仅每条边都要拆成(u to v)和(v to u),而且也难以建边,边数还巨多…
所以我们补集转化一下,如果我们选出的三个人里面,有一个人有两条出边(出边为胜)那么显然这样的图没有贡献
于是对于每个人和每场比赛,都开一个点。
S to 每个人i,建n-1条边,费用为0到n-2
然后每个人i,如果他可能赢下(i,j)比赛的话,就向(i,j)比赛连边。(如果被钦定输了,当然就不连边)
最后每场比赛向T连边。
这样跑出来,就可以在符合题意的情况下,让补集尽量的小,那么答案也就尽量的大了

[BZOJ3774]最优选择

好题,mark

[UVALive5131] Chips Challenge
消除负环的费用流

[JOJ 2453]Candy
贪心决策+网络流

[BZOJ2215][POI2011]Conspiracy
两个点不能同时从独立集蹦到团,所以可行的方法就是:一个人从团到独立集,一个人从独立集到团,或者两个人交换。2-SAT先处理出一种可行的方案,然后枚举情况判断合法即可

[BZOJ2756][SCOI2012]奇怪的游戏
首先,如果行或者列至少有一个是偶数,那么满足二分性(即最后的值取大了一定满足),二分答案+二分图判定即可
如果两个都是奇数,那么由于黑白染色之后,白色格子比黑色格子多1个,而每次操作都是白和黑同时+1。所以唯一合法的最终值,就是初始局面中白色格子-黑色格子所得的值。直接二分图check即可。


DP

[BZOJ1049][HAOI2006]数字序列
第一问,把每个数字变成a[i]-i,然后求出最长不下降子序列即可
第二问,有一个性质,显然对于在不下降子序列里相邻的两个点i,j,中间存在一个分界点使得[i,k]变成刚好从i开始递增,[k+1,j]变成刚好从j开始递减,所以看每个可以转移的位置,然后枚举分界点,计算贡献,细节较多。(数据随机所以可过)MatoNo1的题解
iwtwiioi的题解

[BZOJ1236][SPOJ1433]KPSUM
双倍经验题同2900
就是一个比较简单的数位dp


电子科大的考试

T1:给出一棵树(200000节点),树上的点有权值,并且权值两两不同。现在要求找一个最大的联通子图,满足:将权值升序排序后,第i个点到第i+1个点的路径上(不包括这两个点)经过的点权值均小于第i个点。询问这个联通子图的大小。时间1s空间32M。10组数据。HDU5325

T2:给出一个不超过1e18的数字,要求将这个数字拆分成若干数字乘积,且任意两个数字之差都不超过1,输出所有方案。时间1s空间32M。10组数据

T3:给出一个m条边的正多边形,边数小于等于1e9,边长为1。询问周长最小的正n边形,可以覆盖住给出的多边形,并且中心重合。输出周长,保留4位小数。10组数据

T4:BZOJ4293


ABout 单纯形法

fjzzq‘s BLOG传送门
细语呢喃hrwhisper’s 传送门
Candy’s 传送门

猜你喜欢

转载自blog.csdn.net/Izumi_Hanako/article/details/79362762