ZOJ Monthly, March 2018
A
略
B(大数)
题意:
求的奇偶性
其中n<=10^1000
分析:
等价于求$\biggl\lfloor\frac{n}{1}\biggr\rfloor + \biggl\lfloor\frac{n}{2}\biggr\rfloor+\biggl\lfloor\frac{n}{3}\biggr\rfloor+...+\biggl\lfloor\frac{n}{n}\biggr\rfloor$
这个等于求1~n的因数个数
只有完全平方数的因数个数是奇数,其它的都是偶数,所以这等价于求1~n中完全平方数的个数的奇偶性
即$\biggl\lfloor\sqrt{n}\biggr\rfloor$的奇偶性
因为大数没有封装求根号操作,所以用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
略