【计数】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 }