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;
}

Source

2015 Multi-University Training Contest 1

posted @ 2015-07-28 19:07  ACM_Record  阅读(91)  评论(0编辑  收藏  举报