2015 Multi-University Training Contest 1 OO’s Sequence

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)
 

 

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])\times (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 }
View Code

 

posted @ 2015-07-21 19:52  狂徒归来  阅读(209)  评论(0编辑  收藏  举报