码迷,mamicode.com
首页 > 其他好文 > 详细

trick - 琐记

时间:2020-11-12 14:15:19      阅读:5      评论:0      收藏:0      [点我收藏+]

标签:详解   都对   use   一个   case   max   base   最大独立集   header   

tricks

自定义匹配函数的回文子串问题

主体思想:把平常写的 == 换成任意匹配函数

例题

在这题中,匹配函数为:

\[f(a,b)= \begin{cases} 1 & (a \oplus b=1) \0 & \operatorname{else} \end{cases} \]

然后要你求有多少回文子串。

当然,这个 \(f\) 也可以是任意神奇的函数。

然后我们把这个函数处理出来跑 Manacher 就可以了。它可以求出以任意点为中心的最长回文半径。这样就可以求出最长的回文子串长度,以及回文子串的种类数。

例题代码

曼哈顿距离/切比雪夫距离带权求和

主体思想:二维前缀和拼拼凑凑

例题

这题中,我们发现一个点要求的和的各项系数为 (以 \(k=3\) 为例

0 0 1 0 0
0 1 2 1 0
1 2 3 2 1
0 1 2 1 0
0 0 1 0 0

其中就包含一个

3 2 1
2 1 0
1 0 0

\(s_{i,j}\) 表示 \((i,j)\) 往左上角的二维前缀和。我们发现这个东西就是副对角线(右上->左下)上的二维前缀和的和。

那么整个答案怎么算呢?我们把下面一条副对角线加起来,似乎还多了点啥。

然后发现可以容斥,于是答案为:

(左上,右下两条副对角线的 \(s\) 的和 )-(右上,左下两条主对角线的和)

预处理一下主,副对角线的二维前缀和的和即可。

例题代码

调和级数哈希

主体思想:枚举长度 \(k\),每次用哈希检测答案,复杂度 \(O(\sum \lfloor \dfrac{n}{k}\rfloor * H)\)\(H\) 为哈希复杂度(一般是 \(O(1)\),可能会有 \(log\)

例题1 - 口胡题

例题2

例题1中,评论区神仙 @Tweetuzki 已经讲完了做法;

例题2中,枚举 \(k\) ,然后 \(O(n/k)\) 的跑一遍即可。然而这题还有一个问题,对于一个字符串,我们把它和它的反串视作本质相同的串,这咋哈希?

留到第4个trick里讲。

多属性哈希

主体思想:如果一个元素有若干种属性值,对于属性值一样的元素视作“本质相同的元素”,并且属性值很少;那我们可以把属性值的哈希值排一下序,然后序列哈希。

上一个trick留下的例题2

对于每个串,我们可以认为它有两个“属性值”:原串的哈希值,和反串的哈希值

我们把这两个值排一下序然后哈希即可...

两个数的哈希可以直接做:\((a,b) \rightarrow (a\times base+b)\bmod M\)

例题2代码

“基环树dp”

主体思想:在环上随便钦定两个相邻的点,以两点为根跑树形 \(dp\)

例题

这个做法有一些条件的...这题中,任意断一条边都对,才能这么做

如果断不同的边答案不一样,那就要枚举了,时间复杂度爆炸(有的题里可能不会

回到这题。这题里如果是一颗正常的树,显然是最大独立集问题。

然后我们随便钦定一个环上的 \(u,v\),求 \(max(dp[u][0],dp[v][0])\),即可

例题代码

带根号的数三元环

主体思想:通过某些技巧使复杂度为 \(O(m\sqrt{m})\)

板子

详解见题解。

板子代码

树上主席树

主体思想:处理出树上的DFS序,BFS序,深度...等信息,把计数问题转化成主席树解决的二维数点问题

simple的例题

如果你身经百战,见的多了,这题肯定要秒的

先钦定一个 \(a\),找到一个和它谈笑风生的 \(b\)。如果 \(b\)\(a\) 上面,答案显然是 \((dep[a]-1)\times (size[a]-1)\)

如果 \(b\)\(a\) 下面,那一个 \(b\) 对答案的贡献就是 \(size[b]-1\),其中 \(dep[a]+1\le dep[b] \le dep[a]+k\)

\(b\)\(a\) 下面” \(\rightarrow\) \(in[a]\le dfn[b] \le out[a]\)

然后就变成了两个域限制的问题,其中 \(dfn\) 那个域还是连续不重复的,显然这个好做。以 \(dfn\) 为下标,然后 \(dep\) 为值域,二维带权数点即可。直接用无限续命树做。

例题代码 (被卡常了,估计是被+1s了,直接飞出时限外

主席树维护二分

主体思想:二分每次检测 \(mid\) 的时候序列都不一样,相邻的两个 \(mid\) 改变的并不多,用主席树全部存下来,再维护点啥,每次可以 \(O(log)\) 的检测。

例题

这题暴力二分做法:

对于 \(mid\),大于等于它的视为 \(1\),其它的视为 \(-1\),然后求 \([a,b]\) 区间的最大后缀和,\((b,c)\) 区间的和,\([c,d]\) 区间的最大前缀和,加起来即可。

我们发现这三个都能线段树维护。并且,对于 \(mid\rightarrow mid+1\),只有原来 \(=mid\) 的地方从 \(1\) 变成了 \(-1\)。用 \(vector\) 记录下这些位置,每次修改,总修改次数是 \(n\) 次。直接主席树维护即可。

带上主席树复杂度就是 \(n\log n\),即可求出 \(mid=[1,n]\) 时所有的检测用的数组。然后线段树区间和就可以 \(\log\) 的求,也就是 \(O(\log n)\) 检测一个 \(mid\),套上二分复杂度就是 \(O(\log^2 n)\) 回答每个询问。

(这玩意还是个黑题,太水了吧

例题代码

换根dp

主体思想:先求出以 \(u\) 为根的答案,然后再 \(dfs\) 一遍继承父亲的答案。

例题:树带权重心

先存储每个点往下的带权距离和。

去掉这个点对父亲的贡献,第二遍 \(dfs\) 的时候从父亲更新到儿子,以求出以每个点为根的带权距离和。

例题代码

顺序不变

主体思想:变化是规律的,如果能证出来顺序不变,那直接二分即可

例:第 \(i\) 个数每次都加 \(a_i\),初始为 \(0\)。显然这个顺序不变。每次要求某时刻多少个 \(>k\) 的,直接二分

离线二维偏序问题

主体思想:枚举一维,数据结构维护另一维。

例题:

  1. 区间不同种类数
  2. 逆序对数
  3. 这题 / 另一个链接

线段树节点合并时二分

主体思想:左儿子和右儿子合并的时候,只有右儿子的一段前缀会没有,二分即可

例题:支持修改,求多少个数是前缀最大值

根号讨论

主体思想:小于根号和大于根号的情况分开讨论,平衡总复杂度

例题

\(k>\sqrt{n}\) 的时候暴力跳,当 \(k<\sqrt{n}\) 的时候预处理。

例题代码

信仰线段树

一般要附上势能分析复杂度,当然你直接信仰过也可以

主体思想:线段树+暴力,然而有一些神奇的性质可以保证复杂度为 \(O(nlogn*K)\)

例题1:区间开根下取整,值域在 \([0,10^{12}]\)

每个数被开 \(6\) 次就变成 \(0/1\),而 \(0/1\) 开根取整还是自己,于是不用管了;

于是这题复杂度是 \(O(K*nlogn)\),其中 \(K_{max}=6\)

例题2:区间加正数,区间绝对值和

每个数只会在负变正的时候需要暴力讨论,其它时候绝对值都是-/+

于是 \(K_{max}=1\),然后这题就是个sb题,代码略(其实是没写,百度抄一个

trick - 琐记

标签:详解   都对   use   一个   case   max   base   最大独立集   header   

原文地址:https://www.cnblogs.com/LightningUZ/p/13818191.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!