OO’s Sequence
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 312 Accepted Submission(s): 107
Problem Description
OO has got a array A of size n ,defined a function f(l,r) represent the number of i (l<=i<=r) , that there's no j(l<=j<=r,j<>i) satisfy ai mod aj=0,now OO want to know
[ sum_{i=1}^{n}sum_{j=i}^{n}f(i,j)mod(10^{9}+7) ]
Input
There are multiple test cases. Please process till EOF.
In each test case:
First line: an integer n(n<=10^5) indicating the size of array
Second line:contain n numbers ai(0<ai<=10000)
In each test case:
First line: an integer n(n<=10^5) indicating the size of array
Second line:contain n numbers ai(0<ai<=10000)
Output
For each tests: ouput a line contain a number ans.
Sample Input
5
1 2 3 4 5
Sample Output
23
Source
解题:
需要先使用$sqrt{n}$的时间复杂度把每个数的倍数所在的下标找到
然后我们对每个数,如果她的倍数所在的下标比它大,那么当前这个数是它的倍数左边的约数,求最大的左下标,
如果它的倍数所在的下标比它小,那么当前这个数是它的倍数右边的约数,求最小的右下标
$(i-L[i]) imes (R[i] - i)$就是i所在的区间的个数,这个区间没有它的约数
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn = 10010; 5 const LL mod = 1000000007; 6 vector<int>g[maxn],factor[maxn]; 7 int d[100010]; 8 LL L[100010],R[100010],n; 9 int main() { 10 while(~scanf("%d",&n)) { 11 for(int i = 0; i < maxn; ++i) { 12 g[i].clear(); 13 factor[i].clear(); 14 } 15 for(int i = 1; i <= n; ++i) { 16 scanf("%d",d+i); 17 g[d[i]].push_back(i); 18 L[i] = 0; 19 R[i] = n+1; 20 } 21 for(int i = 1; i <= n; ++i) { 22 for(int j = 1,m = sqrt(d[i]); j <= m; ++j) { 23 if(d[i]%j) continue; 24 int tmp = d[i]/j; 25 if(g[tmp].size()) factor[tmp].push_back(i); 26 if(tmp == j) continue; 27 if(g[j].size()) factor[j].push_back(i); 28 } 29 } 30 for(int i = 1; i <= n; ++i) { 31 for(int j = factor[d[i]].size()-1; j >= 0; --j) { 32 int now = factor[d[i]][j]; 33 if(now < i) R[now] = min(R[now],(LL)i); 34 if(now > i) L[now] = max(L[now],(LL)i); 35 } 36 } 37 LL ret = 0; 38 for(int i = 1; i <= n; ++i) 39 ret = (ret + (i - L[i])*(R[i] - i)%mod)%mod; 40 cout<<ret<<endl; 41 } 42 return 0; 43 }