HDU5288.OO’s Sequence(多校第一题)

来源:互联网 发布:网络机漏洞检测软件 编辑:程序博客网 时间:2024/05/16 08:31

枚举每一个i,用筛选法算出每一个a[i]满足的足有端点,记为l,r,
则对于这个端点有(i-l+1)*(r-i+1)个数满足题目所要求的
以此类推

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <ctime>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;#define INF 0x3f3f3f3f#define inf -0x3f3f3f3f#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define mem0(a) memset(a,0,sizeof(a))#define mem1(a) memset(a,-1,sizeof(a))#define mem(a, b) memset(a, b, sizeof(a))typedef long long ll;const int maxn=100010;const __int64 MOD=1000000007;int a[maxn];int vis[100100];int leften[maxn];int righten[maxn];int main(){    int n;    while(scanf("%d",&n)!=EOF){        int maxv=0;        for(int i=0;i<n;i++){            scanf("%d",&a[i]);            maxv=max(a[i],maxv);        }        mem1(vis);        for(int i=0;i<n;i++){            if(vis[a[i]]==-1)                leften[i]=i+1;            else                leften[i]=i-vis[a[i]];            for(int j=a[i];j<=maxv;j+=a[i])                vis[j]=i;        }        mem1(vis);        for(int i=n-1;i>=0;i--){            if(vis[a[i]]==-1)                righten[i]=n-i;            else                righten[i]=vis[a[i]]-i;            for(int j=a[i];j<=maxv;j+=a[i])                vis[j]=i;        }        __int64 ans=0;        for(int i=0;i<n;i++){            ans+=(__int64)leften[i]*(__int64)righten[i];            ans%=MOD;        }        printf("%I64d\n", ans);    }    return 0;}[ Copy to Clipboard ]    [ Save to File]
0 0
原创粉丝点击