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]的因子;

    最后还有就是分块思想;

  • 相关阅读:
    C#中的Singleton模式
    CodeLib
    Google Chats 居然和Gmail集成了...
    Windows中OSG环境搭建
    Socket中winsock.h和winsock2.h的不同
    高斯日记 蓝桥杯
    MATLAB矩阵处理
    马虎的算式 蓝桥杯
    MATLAB基础
    矩阵相乘的一维数组实现
  • 原文地址:https://www.cnblogs.com/Rlemon/p/3349754.html
Copyright © 2011-2022 走看看