【计数】hdu 4466 Triangle

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

        很好玩到一道题。

        

View Code
 1 //By Lin
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector>
 6 #define maxL 5000000
 7 #define MOD  1000000007
 8 #define sqr(x) ((x)*(x))
 9 using namespace std;
10 typedef long long LL;
11 
12 int        num[maxL+100],g[maxL+100];
13 int        ans[maxL+100],n;
14 vector<int> data;
15 
16 int        quick_sqr(int k){
17     k--;
18     LL    ret = 1, g = 2;
19     while ( k ) {
20         if ( k&1 ) ret = ret*g%MOD;
21         g = g*g%MOD;
22         k >>= 1; 
23     }
24     return ret;
25 }
26 int        main()
27 {
28     for (int x = 1; 3*x<=maxL; x++){
29         g[x*3]++;
30         if ( 4*x<=maxL ) g[4*x]--;
31     }
32     for (int L = 1; L<=maxL; L++){
33         num[L] = num[L-1]+g[L];
34         num[L] %= MOD;
35         g[L+2] += g[L];
36         g[L+2] %= MOD;
37     }
38     int tt = 0; 
39     memset( ans , -1 , sizeof(ans) );
40     ans[1] = 1;
41     while ( ~scanf("%d", &n ) ) {
42         int output = 0; 
43         data.clear();
44         for (int x = 1; sqr(x)<=n; x++ ) if ( n%x == 0 ) {
45             data.push_back(x);
46             if ( sqr(x)!=n ) data.push_back(n/x);
47         }
48         sort( data.begin() , data.end() );
49         for (int i = 1; i<data.size(); i++ ) {
50             if ( ans[data[i]] != -1 ) continue;
51             ans[data[i]] = quick_sqr(data[i]);
52             for (int j = 1; j<=i; j++ ) if ( data[i]%data[j] == 0 ) {
53                 ans[data[i]] -= ans[data[i]/data[j]];
54                 ans[data[i]] += MOD;
55                 ans[data[i]] %= MOD;
56             }
57         }
58         for (int i = 0; i<data.size(); i++ ){
59             output += ((LL)num[data[i]])*ans[n/data[i]]%MOD;
60             output %= MOD;
61         }
62         printf("Case %d: %d\n" ,++tt, output );
63     }
64     return 0;
65 }
posted @ 2012-11-20 16:26  lzqxh  阅读(225)  评论(0编辑  收藏  举报