zoukankan      html  css  js  c++  java
  • 莫比乌斯反演

    hdu 4676 http://acm.hdu.edu.cn/showproblem.php?pid=4676

    题意:给你1..n的排列,给一个区间[L,R],返回gcd(a[i],a[j]) L<=i<j<=R的和;

    分析:

    对于一个区间[L,R],我们设g(d) 表示在区间内gcd(a[i],a[j]) = d的个数 ;

    f(d) 表示在区间内gcd(a[i],a[j]) = d的倍数的个数;

    显然 f(d) = sigma{ d | n, g(n) };

    通过莫比乌斯反演得到  g(d) = sigma{  d | n, mu(n/d) * f(n) };其中mu()是莫比乌斯函数;

    g(d) = mu(1) * f(d) + mu(2) * f(2*d) + ... + mu(n/d) * f(n);

    设num[d]表示在区间内a[i]是d的倍数的个数;

    显然 f(d) = C(num[d] , 2);

    那么 ans = 1*g(1) + 2 * g(2) + 3 * g(3) + .. + n * g(n); (最大公约数最大是n);

    g(1) = mu(1)*f(1) + mu(2) * f(2) + ... + mu(n) * f(n);

    g(2) = mu(1)*f(2) + mu(2) * f(4) + ... + mu(n/2) * f(n);

    .....

    合并同类项:

    ans = sigma( f(d) * w(d) ); 其他w(d) = sigma( a | d , mu(d/a) *a  );

    我们可以用nlogn的时间预处理出来w(d); 

    这样当我们插入一个数a[k]时,将会使num[d], (d | a[k]) 改变,

    这样 ans += (C(num(d)+1,2) - C(num(d),2)) * w(d); 

    化简后就是 ans += num(d) * w(d);  

    删去一个数类似;

    同样我们可以用nlogn的时间预测理出a[k]的因子;

    最后还有就是分块思想;

  • 相关阅读:
    nginx 配置 开发
    导入excel 数据到mysql出现的时间格式
    gradle 集成到myeclipse
    多线程同步和异步的方式
    谈一下spring 的理解
    java 中的反射
    Sublime Text 下配置python
    Python元组的简单介绍
    Python中strip()函数
    Python中的repr()函数
  • 原文地址:https://www.cnblogs.com/Rlemon/p/3349754.html
Copyright © 2011-2022 走看看