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
  • 相关阅读:
    题解 CF171G 【Mysterious numbers
    题解 P1157 【组合的输出】
    题解 P3955 【图书管理员】
    题解 P2036 【Perket】
    题解 CF837A 【Text Volume】
    题解 CF791A 【Bear and Big Brother】
    题解 CF747A 【Display Size】
    题解 P1332 【血色先锋队】
    题解 P2660 【zzc 种田】
    题解 P4470 【[BJWC2018]售票】
  • 原文地址:https://www.cnblogs.com/idy002/p/4381789.html
Copyright © 2011-2022 走看看