[USACO08DEC]Patting Heads
这题还是比较水的。首先O(n2)模拟显然过不了,那就换一种思路,考虑每一个数对答案的贡献,显然一个数a[i]会对后面的a[i] * 2, a[i] * 3,a[i] * 4……都贡献1,。那么就想线性求因数个数一样,对于每一个a[i],都计算出对能被他整出的数的贡献。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter printf("\n") 13 #define space printf(" ") 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const int eps = 1e-8; 19 const int maxn = 1e5 + 5; 20 const int max_size = 1e6 + 5; 21 inline ll read() 22 { 23 ll ans = 0; 24 char ch = getchar(), last = ' '; 25 while(!isdigit(ch)) {last = ch; ch = getchar();} 26 while(isdigit(ch)) 27 { 28 ans = ans * 10 + ch - '0'; ch = getchar(); 29 } 30 if(last == '-') ans = -ans; 31 return ans; 32 } 33 inline void write(ll x) 34 { 35 if(x < 0) x = -x, putchar('-'); 36 if(x >= 10) write(x / 10); 37 putchar(x % 10 + '0'); 38 } 39 40 int n, a[maxn]; 41 int num[max_size], Max = 0, ans[max_size]; 42 43 int main() 44 { 45 n = read(); 46 for(int i = 1; i <= n; ++i) 47 { 48 a[i] = read(); 49 Max = max(Max, a[i]); 50 num[a[i]]++; //开一个桶 51 } 52 for(int i = 1; i <= Max; ++i) if(num[i]) 53 for(int j = i; j <= Max; j += i) ans[j] += num[i]; 54 for(int i = 1; i <= n; ++i) write(ans[a[i]] - 1), enter; //因为还有他自己,所以要减1 55 return 0; 56 }