心得(一)

存在函数 _is(x) 表示 x 是否满足某种性质 ,满足性质函数=1,反之=0

存在函数 :

求:

一下提供两个思路求解

题目参考链接https://codeforces.com/contest/2091/problem/E

题目描述:存在多少对a,b st. 1<=a<b<=n 并且 lcm(a,b)/gcd(a,b)为素数

思路:lcm(a,b)/gcd(a,b)=(a/gcd(a,b))*(b/gcd(a,b))为素数 排除两种可能后得 a=gcd(a,b) 且 b%a==0 且 isprime(b/a)==1

即对于1<=i<j<=n 枚举每个i 找到所有x st.i*x<=n 且 isprime(x) 即 求sumprime(n/i)

问题转化为求

每种思路都要先用筛 预处理出1e7以内所有素数(或者打表)

思路一:

在O(根号n)时间复杂度内可以解决问题

但是对于最上面的问题,不能每次都找到一个展开式将On时间复杂度降到O根号n时间复杂度

于是有了思路二:

这里只需遍历每个素数,对于每个素数,他在n/i上都有贡献,累加贡献就好

打表的话时间复杂度为O(Π(n))=O(n/logn) 似乎没有O(根号n)时间复杂度要好,但是对于大多数求解最上面问题的时候,只能去寻找_is(i)对于问题f(i)的贡献

https://ac.nowcoder.com/acm/contest/104420/A

这里以这道题为例

题目描述 :存在多少对a,b st. 1<=a<b<=n 并且 a+b=x^2 并且 x为正整数

即 对于每个i st.i<j<=n && j=x^2-i 等价于 对于每个i 2*i<x^2<=n+i 找到 (2*i,n+i] 范围内所有x^2

即求:

sumpowx(i)表示 i 以内包含多少个x^2

也就是求解最上面那个公式

若直接求解考虑二分,时间复杂度依旧有Onlogn 递推也无法降低时间复杂度

那么只能通过思路二 枚举每个x^2求解

对于求解这个问题

枚举x^2 找到他在n+i上的贡献,若x^2<=n+1 对于n+1到n+n-1每个都有贡献 res+=n-1 ,若x^2>n+1 则找到x^2=n+j

j=x^2-n 大于等于 j 的所有i有 2*n-x^2 个,res+=2*n-x^2 1<=x^2<=n+n-1

同理后面sumpowx求和依旧通过找贡献求得

枚举x^2只需枚举根号n个 时间复杂度降到O根号n

总结:对于求 _sum(f(i)) 求和的问题,可以通过找到 _is(i) 在 f(i) 上的贡献求和,如果数学功底好可以尝试递推出其他式子

全部评论

相关推荐

评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务