2015 Multi-University Training Contest 1 1001(HDU 5288) OO’s Sequence
题目
http://acm.hdu.edu.cn/showproblem.php?pid=5288
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).
\]
题意
\(f(l, r)\)定义为对于任意\(i(l<=i<=r)\), 不存在\(j(l <= j <= r, j!= i)\)使得Ai mod Aj = 0.
即对于任意Ai ,其所在区间(l, r)内不存在Ai的因数,求i的总个数
解法
对于Ai寻找其左右最近的因子Al , Ar
则Ai对于ans的贡献为(i-l)*(r-i)
vis[i]表示i对后出现的位置
代码
#include <cstdio>
#include <cstring>
const int N = 10000;
const int MAXN = 100010;
const int MOD = 1e9 + 7;
int num[MAXN], vis[MAXN], left[MAXN], right[MAXN];
int main() {
int n;
while(~scanf("%d", &n)) {
for(int i = 1; i <= n; i++) {
scanf("%d", &num[i]);
}
for(int i = 1; i <= n; i++) {
left[i] = 0;
right[i] = n + 1;
}
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; ++i) {
for(int j = num[i]; j <= N; j += num[i]) {
if(vis[j] != 0 && right[vis[j]] == n + 1) {
right[vis[j]] = i;
}
}
vis[num[i]] = i;
}
memset(vis, 0, sizeof(vis));
for(int i = n; i > 0; --i) {
for(int j = num[i]; j <= N; j += num[i]) {
if(vis[j] != 0 && left[vis[j]] == 0) {
left[vis[j]] = i;
}
}
vis[num[i]] = i;
}
int ans = 0;
for(int i = 1; i <= n; i++) {
ans = (ans + (i - left[i]) * (right[i] - i)) % MOD;
}
printf("%d\n", ans);
}
return 0;
}