ZOJ Monthly, March 2018

A

B(大数)

题意:

  求的奇偶性

  其中n<=10^1000

分析:

  等价于求$iggllfloorfrac{n}{1}iggr floor + iggllfloorfrac{n}{2}iggr floor+iggllfloorfrac{n}{3}iggr floor+...+iggllfloorfrac{n}{n}iggr floor$

  这个等于求1~n的因数个数

  只有完全平方数的因数个数是奇数,其它的都是偶数,所以这等价于求1~n中完全平方数的个数的奇偶性

  即$iggllfloorsqrt{n}iggr floor$的奇偶性

  因为大数没有封装求根号操作,所以用java或者python实现牛顿迭代就行了

C(组合计数)

D(树形dp)

题意:

  有一个n个点的树,每个节点上有一个数字,0/1/-1,为-1的数字可以变成0或者1

  考察树上所有边相连的两个点,如果这两个点数字不同,则++ans

  寻找一个-1变成0/1的方案使得最终ans最小

  n<=1e5

分析:

  简单的树形dp

E(二维数点)

题意:

  有一个n个点的树,有q组询问,每组询问l,r

  若一个点v满足l<=v<=r,则该点被称为good point

  若一条树边两端的点都是good point,那么这条树边就是good edge

  对于每组询问,我们拿出所有的good point和good edge组成子图,需要回答这个子图连通块的个数

  n,q<=1e5

分析:

  求连通块个数这个不是一个很简单的东西

  不过因为这是一个树,所以子树是一个森林,所以连通块个数=点数-边数

  点数就恰好是r-l+1,主要就是要求边数

  求边数其实就是求有多少边(u,v)(假设u<=v)满足l<=u,v<=r

  这就是个二维数点问题,直接扫描线+BIT解决

  时间复杂度O(nlogn)

F(线段树处理循环节)

题意:

  

  n<=1e5

分析:

  模数很小,所以考虑找循环节

  打表发现每个数的最小循环节都是48的因子,所以我们可以把48当作每个数的循环节

  对于线段树上的每个区间[l,r],我们记下一个f[0..47],其中f[i]表示把这个区间整体操作i次得到的和

  对于修改操作“给一个区间[l,r]操作一次”,就相当于将这个区间的f[0..47]整体循环左移一次

  对于询问操作,答案就是f[0]

  时间复杂度O(48*nlogn)

G(Hash计数)

题意:

  有一串长度为n的珠子串成一个环,每个位置都是一个小写英文字母。

  如果我们可以删除一个长度为i的连续的一端,剩下来的循环珠子满足“相邻位置的字母都不同”这一条件,那么ans[i]=1

  最后需要输出ans[0..n-1]

  n<=1e6

分析:

  首先加长两倍,把环变成链,删除一段等价于留下一段,于是我们的任务就变成下面的:

  如果可以在新的字符串s中找到一个长度为i的字符串,满足这个字符串相邻位置的字母都不同且首位字母不同,则ans[n-i]=1

  我们把s分成若干段,每段都是极大的“字符串相邻位置的字母都不相同”子串,能产生答案的字符串一定会在每个分段里,不会跨越分界线

  现在我们来枚举i,判断保留长度为i的字符串是否可行,如何判断呢?

  我们发现,如果这个i行不通,那么就说明对于每个位置j都有s[j]=s[j+i-1],这也就等价于该子串长度为len-i+1的前缀和长度为len-i+1的后缀是完全相同的

  如何判定这一点呢?直接Hash就行了

  时间复杂度O(n)

H(dp)

I(kdtree)

题意:

  平面上有n个点和m条线段,线段是以(ai,0)-----(0,bi)形式给出的,现在对于每条线段都要回答它穿过了多少个点

  点的坐标是随机生成的

  n,m<=1e5

分析:

  因为点的坐标是随机生成的,所以每条直线穿过的点数不会很多,我们考虑通过来优化暴力实现

  我们可以把所有点建成一个kdtree,然后对于每个询问线段在kdtree中寻找答案,如果当前节点的范围矩形和线段不相交就退出

  因为点的坐标是随机生成的,所以对于每个询问,复杂度都不会很高,kdtree就能够顺利AC

J

原文地址:https://www.cnblogs.com/wmrv587/p/8559600.html