首页 > 其他 > 详细

bzoj 2693

时间:2015-03-31 19:52:53      阅读:83      评论:0      收藏:0      [点我收藏+]

 

收获:

  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\n", calc(n,m) );
69     }
70 }
View Code

 

bzoj 2693

原文:http://www.cnblogs.com/idy002/p/4381789.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!