zoukankan      html  css  js  c++  java
  • bzoj 2693

    收获:

      1、积性函数的积也是积性函数,基本的积性函数:常数函数,正比例函数,欧拉函数,Mobius函数,积性函数一般都知道表达式,所以一般都可以在线性筛时搞定。

      2、遇到整除求和时,这个东西就已经是最简了,所以可以考虑提出它,然后尝试搞后边的东西的前缀和,如果可以成功,那么就可以在O(sqrt(n))的复杂度做了。

     1 /**************************************************************
     2     Problem: 2693
     3     User: idy002
     4     Language: C++
     5     Result: Accepted
     6     Time:4692 ms
     7     Memory:118504 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <iostream>
    12 #define M 100000009
    13 using namespace std;
    14  
    15 typedef long long dnt;
    16  
    17 int prm[10010], isnot[10000010], mu[10000010], dm[10000010], ptot;
    18  
    19 void init( int n ) {
    20     mu[1] = 1;
    21     dm[1] = 1;
    22     for( int i=2; i<=n; i++ ) {
    23         if( !isnot[i] ) {
    24             prm[++ptot] = i;
    25             mu[i] = -1;
    26             dm[i] = (dnt)i*(1-i) % M;
    27         }
    28         for( int j=1; j<=ptot && i*prm[j]<=n; j++ ) {
    29             int k = i*prm[j];
    30             isnot[k] = true;
    31             if( i%prm[j]==0 ) {
    32                 mu[k] = 0;
    33                 dm[k] = (dnt)k/i*dm[i] % M;
    34                 break;
    35             }
    36             mu[k] = -mu[i];
    37             dm[k] = (dnt)dm[i]*dm[prm[j]] % M;
    38         }
    39     }
    40     for( int i=1; i<=n; i++ ) {
    41         dm[i] += dm[i-1];
    42         if( dm[i]>=M ) dm[i]-=M;
    43         if( dm[i]<0 ) dm[i]+=M;
    44     }
    45 }
    46 inline dnt S( dnt n, dnt m ) {
    47     return ((1+n)*n/2%M) * ((1+m)*m/2%M) % M;
    48 }
    49 dnt calc( int n, int m ) {
    50     if( n>m ) swap(n,m);
    51     dnt rt = 0;
    52     for( dnt d=1; d<=n; d++ ) {
    53         dnt dd = min( n/(n/d), m/(m/d) );
    54         rt += S(n/d,m/d) * (dm[dd]-dm[d-1]) % M;
    55         if( rt>=M ) rt-=M;
    56         if( rt<0 ) rt+=M;
    57         d = dd;
    58     }
    59     return rt;
    60 }
    61 int main() {
    62     init(10000000);
    63     int T;
    64     scanf( "%d", &T );
    65     while( T-- ) {
    66         int n, m;
    67         scanf( "%d%d", &n, &m );
    68         printf( "%lld
    ", calc(n,m) );
    69     }
    70 }
    View Code
  • 相关阅读:
    致5年后的自己
    基础知识回顾——属性
    基础知识回顾——类和对象
    基础知识回顾——面向对象编程
    基础知识回顾——函数
    基础知识回顾——流程控制
    基础知识回顾——列表和字典
    基础知识回顾——元组和字符串
    基础知识回顾——通用序列操作
    XPath Checker和Firebug安装与使用
  • 原文地址:https://www.cnblogs.com/idy002/p/4381789.html
Copyright © 2011-2022 走看看