Loading

省队培训day3

day3

考试题目

T1

定义 \(f(x)\) 的值为 \(x\) 的所有因子的异或和。给定一个数 \(n\) ,要求 \(f(1)\bigoplus f(2)\bigoplus f(3)...f(n)\)

其中 \(n\leq 10^{14}\)

  • 解析:
  • 我们考虑把所有的 \(f\) 拆开,考察任意一个数 \(k\) 在完全展开的式子中出现了几次。显然,一共出现了 \(\left\lfloor\tfrac{n}{k}\right\rfloor\) 次,这是因为当且仅当 \(p\)\(k\) 的倍数时,\(k\) 才会出现一次,而在 \([1,n]\) 中一共有 \(\left\lfloor\tfrac{n}{k}\right\rfloor\)\(k\) 的倍数。
  • 同时,异或运算具有交换律和结合律,所以我们考虑 \(\left\lfloor\tfrac{n}{k}\right\rfloor\) 的奇偶性,如果是奇,那么就说明有一个 \(k\) 剩了下来,其余都两两异或变成 \(0\) 了,如果是偶,那么就说明一个都没有剩下,全部异或成 \(0\) 了。至此,我们有了一个复杂度为 \(O(n)\) 的算法。
  • 我们需要一个更优的算法,观察到 \(\left\lfloor\tfrac{n}{k}\right\rfloor\) 可以用数论分块进行优化,那么我们现在需要解决的问题是如何计算一段连续的数的异或和。
  • 注意到如果 \(a\) 是一个奇数,那么有 \(a\bigoplus (a-1)=1\) ,所以我们只需要注意这个连续数的长度的奇偶性,左端点的奇偶性,序列长度一半的奇偶性就可以了。

T2

给出 \(n\) 条水平线段和铅锤线段,称两条线段联通当且仅当两条线段有交点。称线段 \(a\) 是关键的,当且仅当存在两条线段 \(b,c\) 使得 \(a\) 在时 \(b,c\) 联通, \(a\) 不在时 \(b,c\) 不连通。

  • 解析:
  • 考试就想出来一个 \(O(n^2)\) 做法,把二分图建出来求割点。十分暴力
  • 正解可以用主席树优化建图,然后再主席树上 dfs ,合并信息。

T3

给一棵树,支持单点修改,单点所在联通块修改,维护同色联通块信息。

  • 解析:

  • 考试就想出来一个 \(O(n^2)\) 做法。

  • 正解:

  • 点同色连通块的括号序列对应于所在的边同色联通块的括号序列的一个区间,点同色联通块的信息时边同色联通块的一个子树,因为边同色连通块的信息时边同色联通块的一个子树,因为边同色连通块只比点同色连通块多一条边。

  • 因为点的连通块没有均摊,但是边的联通块有均摊,所以维护边的联通块而不是点的联通块
    可以发现改变一条边的颜色只影响 \(O(1)\) 个边同色连通块,而点同色连通块可能影响 \(O(n)\)
    把点连通块转边连通块就是把每个点 \(x\) 的点权放在 \(x\) 到父亲 \(fa[x]\) 的边上,这样的边连通块。

  • 于是问题可以转化为:
    边权
    1.单边修改
    2.修改一条边所在同色块的颜色
    3.查询一条边所在同色块的最浅点和最深点

  • 通过对每个极大边连通块开一个 ETT 来维护
    然后每个 ETT 上面每个节点维护 \(O( c )\) 个信息,表示这个节点为根的子树里面有没有节点的儿子为 \(1,2…c\) 这种颜色

  • ETT 就是平衡树。

  • 当把这个连通块染色为某个颜色\(x\)的时候
    while( root的x颜色信息为1 ) 沿着 ETT 结构递归下去,直到找到一个点其满足至少有一个儿子颜色为 \(x\) 颜色
    然后把这个点的所有颜色为 \(x\) 的儿子的 ETT 合并进这个ETT里面
    这个通过对每个点开一个 \(O( x )\) 的数组来存下每个颜色的儿子节点就可以做到了
    具体体现在操作上就是合并两棵平衡树,把其中一个平衡树完全合并进另一个平衡树,作为一个区间

  • 这样以 \(O( clogn )\) 代价,我们减少了 \(O( 1 )\) 个联通块
    每次最多加 \(2 = O( 1 )\) 个联通块
    所以时间复杂度是均摊 \(O( ( n + m )clogn )\)

  • 点染色就转化为了边染色,可能会合并连通块,这个是平凡的
    \(x\)\(a\) 染成 \(b\),要把 \(x\) 为根的 \(b\) 色连通块和 \(fa(x)\) 为根的 \(b\) 色连通块和边 \((x,fa(x))\) 合并
    查询的话,ETT 上面维护:最浅,最深的 \(dep\),这个联通块的颜色 \(size\)
    这样就做完了
    时间复杂度 \(O( nc\log n )\),空间复杂度 \(O( nc )\)

  • 发现我们ETT每个节点维护了 \(O( c )\) 个信息
    \(O( c )\) 个信息是 \(or\) 起来的
    所以可以压位维护
    时间复杂度 \(O( nlogn(1+c/w) )\),空间复杂度 \(O( n(1+c/w) )\)

后面 T2 和 T3 都没有听懂,前置知识落下太多了。

杂题选讲

Bzoj4241历史研究

  • 序列,定义 \(Chtholly(l,r,x)\)\(x\) 在区间 \([l,r]\) 中出现次数,查询一个区间中最大的 \(x*Chtholly(l,r,x)\)

可能出现的答案只有 \(n\)
和刚刚那个题类似,一个数 \(x\) 出现次数为 \(y\) ,则答案有可能为
\(x\times 1,x\times2...x\times y\)
于是将这些可能的值放一起离散化
然后就可以套用值域分块来
\(O( n\sqrt m + m\sqrt n )\) 做了

[Ynoi2015]いずれその陽は落ちるとしても

  • 给你一个序列 \(a\),每次查询一个区间 \([l,r]\)

这个区间一共可以形成 \(2^{(r-l+1)}\) 个子序列,即每个数出现或者不出现,定义一个子序列对答案的贡献为其去重之后的和,即如果一个数x在这个子序列里出现了多次,那么只算一次。
查询区间[l,r]里面每个子序列的贡献的和。
然而由乃为了让这个题变麻烦,所以每次的膜数不一样。

考虑单次的询问我们如何计算,对于数 \(x\) ,假设出现了 \(y\) 次,区间长度是 \(len\) ,那么 \(x\) 对答案的贡献是 \(x(2^{len}-x^{len-y})\) ,而 \(2^{len-y}\) 次方是除了 \(x\) 以外的数有多少个不同的子序列,这些对 \(x\) 的贡献没有影响。

\(2^y-1\) 是所有 \(x\) 构成的子序列中有 \(2^y-1\) 种至少包含一个 \(x\) ,有 \(1\) 种不包含 \(x\)

如果模数相同,那么我们可以用莫队维护。

注意到贡献分为 \(x2^{len}\)\(-x\times 2^{len-y}\) ,其中第一个部分非常好维护,而第二部分我们可以分块处理,这是因为一个区间只有 \(O(\sqrt n)\) 种不同的出现次数。

因为 \(1+2+...\sqrt n=O(n)\),所以我们可以用一个均摊的莫队来维护区间可能的出现次数,从而维护区间中所有出现次数,关于快速幂我们可以直接预处理出来,或者利用以前快速幂的信息 \(O(\log (y-x))\) 算出,这样的话复杂度是 \(O(\sqrt n)\)

Luogu3245 HNOI2016大数

  • 给一个数字串和一个素数 \(p\) ,多次查询这个数字串的一个子串里有多少个子串是 \(p\) 的倍数。

我们记 \(suf_i\) 为左端点为 \(i\) 的后缀串组成的数,如果对于 \(l,r\) ,有 \(suf_l\equiv suf_{r+1}\bmod p\),则 \(s_{l,r}\times 10^{n-r-1}\)\(p\) 的倍数。我们对 \(p=2,5\) 时特判,如果不是 \(2,5\) ,那么就有 \(p|s_{l,r}\) ,离散化一下,就变成小 z 的袜子了。

Luogu3604 美好的每一天

  • 给一个小写字母的字符串,每次查询区间有多少子区间可以重排成为一个回文串。

上面那个重排成为一个回文串等价于要么所有数都出现偶数次,要么只有一个数出现奇数次。

我们要维护奇偶性,这使我们想到异或,我们令:\(a\to 1,b\to 2,c\to 4,...z\to 2^{25}\) ,那么所有数出现偶数次等价于异或和为 \(0\) ,有一个出现次数等价于异或值为 \(2\) 的幂。

于是问题变成了有多少组 \((i,j)\) 使得异或值满足上述要求。

莫队每一检查 \(26\) 个字母就可以了。

时间复杂度 \(O(n\sqrt nc)\)

查询区间逆序对个数

用可持久化块状树和莫队可以优化到 \(O(n\sqrt m)\)

但是我没有听懂。

Bzoj4358 permu

  • 查询一个区间中最长的值域连续段,值域连续段 \([x,y]\) 即区间中存在 \([x,y]\) 内的所有数,值域连续不意味着序列上连续。

若维护当前区间 \([l,r]\) 中每个值向左右延伸到的最远位置
实际只要维护值域的每个边缘点向另一侧延伸的最远位置
可以 \(O(1)\) 转移到 \([l,r+1]\)\([l-1,r]\)
但是这个由于是个取 \(max\) 的过程,所以不支持删除
于是可以套用不删除莫队的做法即可

除非强制在线,不然静态分块一定不如莫队

3个经典问题

  1. 给一个序列,每次查询一个区间的众数,强制在线。
  2. 查询区间逆序对,强制在线。
  3. 多次查询一个区间内的 \([l,r]\) 中最小的 \(|a_i-a_j|,l\le i,j\le r\)

以上三个题都没有听懂。

根号分治经典题

  • 给定一张 \(n\) 个节点 \(m\) 条边的无向图,其中 \(n,m,q\le1e5\) ,我们有两个操作,把 \(x\) 的点权加上 \(y\) ,或是查询 \(x\) 相邻的点权和。

图中所有点的度数和是 \(m\) ,我们可以对这个度数进行根号分治,度数 \(\geq \sqrt m\) 的点最多只有 \(\sqrt m\) 个,而度数小于 \(<\sqrt m\) 的点点数不足 \(\sqrt m\) 个。

我们对每个度数 \(\geq \sqrt m\) 的点维护答案,度每个度数 \(<\sqrt m\) 的点暴力修改,复杂度 \(O(q\sqrt m)\)

SHOI2006 Homework

维护一个集合,支持两个操作:

  • \(1,x\):表示在集合 \(S\) 中加入一个 \(x\)
  • \(2,y\):表示在当前的集合中询问所有 \(x\bmod y\) 最小的值。

这个题我们考虑根号分治,对于 \(\sqrt n\) 以内的 \(y\) ,每次修改即更新所有这个的答案。对于 \(\sqrt n\) 以上的 \(y\) ,则需要进行一些操作,我们对值域分块,维护出块内其前面最近的 \(x\),如果没有,则维护出其最近的有 \(x\) 的块。

修改的时候,我们同时维护以上信息。

总时间复杂度:\(O(m\sqrt v)\)

Luogu3591 [POI2015]ODW

这个没有听懂。

[Ynoi2015]いまこの時の輝きを

这个没有听懂。

[Ynoi2009] ra1rmdq

这个没有听懂

[Ynoi2011]D2T2

这个没有听懂

[Ynoi2019]宝石之国

一个通用的任意范围的离线范围修改查询算法

离线算法的优势是我可以提前知道每个修改查询范围,从而在其上面设计针对的数据结构
先考虑查询不超过 \(\sqrt m\) 次的情况
区域数:\(f(x)\) 表示 \(x\) 次修改查询会将全集划分为多少个等价类,使得每个等价类中的每个元素经过了同样的修改与查询
这里 \(f(x)=O(x^2)\)

对操作序列进行分治,分治树越上层的节点中,划分的区域越细化
分治树的叶子上只有一个半平面,\(2\) 个区域

从父亲节点 DFS 到儿子时,需要把一些在儿子中是等价类,在父亲中不是等价类的区域合并,过程中需要合并信息
从儿子节点返回到父亲时,需要把一些在儿子中是等价类,在父亲中不是等价类的区域分裂,过程中需要下放标记
到分治树叶子节点处,修改操作可以打标记处理,查询操作可以直接查询信息
前者对应于信息合并,后者对应于标记下放
这个算法可以离线任何分治数据结构,如线段树, KDT 等

样在代数结构上的操作次数是多少?
\(m\) 次操作:
\(T(m)=2T(\frac{m}{2})+f(m)\)
\(T(m)=2T(\frac m 2)+O(m^2)\)
T\((m)=O(m^2)\)
将时间按 \(O(sqrtn)\) 大小分块,每次处理 \(m=sqrtn\) 次询问
上一个时间块处理完后,需要重新划分一下下一个时间块的等价类,这个过程需要把所有点上的标记和值合并,同时合并一些等价类的值

小结

因为前置知识的缺失,听起来十分费劲,一些曾经想都不敢想的东西也可以实现,这提醒我路漫漫其修远兮,应该继续努力学习,不浪费时间。目前先把前置知识补完,再进一步落实培训内容。

posted @ 2021-06-01 21:07  hyl天梦  阅读(101)  评论(0编辑  收藏  举报