hdu 5288 OO’s Sequence(two pointers)

来源:互联网 发布:rf mems 知乎 编辑:程序博客网 时间:2024/06/05 17:46

OO’s Sequence

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5288

解题思路:

官方题解:

定义两个数组L[i],R[i],表示第i个左侧和右侧最接近它且值是a[i]因子的数字的位置,那么第i个数能贡献的答案就是(R[i]-i)*(i-L[i]),因此每个数字x都去枚举它的因子y,然后左右找到一个值y且最接近x的数,然后用他的位置更新一下L,R数组。时间复杂度O(nsqrt(a))。

AC代码:

#include <iostream>#include <cstdio>#include <cstring>#define MOD 1000000007using namespace std;typedef long long ll;const int N = 100005;int n;ll l[N],r[N];int pre[N],last[N];int a[N];int main(){    while(~scanf("%d",&n)){        for(int i = 1; i <= n; i++){            scanf("%d",&a[i]);            l[i] = 1;r[i] = n;        }        memset(pre,0,sizeof(pre));        memset(last,0,sizeof(last));        for(int i = 1; i <= n; i++){            for(int j = a[i]; j <= 10000; j += a[i])                if(pre[j] != 0 && r[pre[j]] == n)//如果已经出现并且在右边最近的因子还没有找到                    r[pre[j]] = i-1;            pre[a[i]] = i;        }        for(int i = n; i > 0; i--){            for(int j = a[i]; j <= 10000; j += a[i])                if(last[j] != 0 && l[last[j]] == 1)//如果已经出现并且在左边最近的因子还没有找到                    l[last[j]] = i+1;            last[a[i]] = i;        }        /*        for(int i=1;i<=n;i++)            printf("%d %d %d\n",i,l[i],r[i]);        */        ll ans = 0;        for(int i = 1; i <= n; i++)            ans = (ans+(ll)(i-l[i]+1)*(ll)(r[i]-i+1)%MOD)%MOD;        printf("%lld\n",ans);    }    return 0;}



0 0