您的位置:首页 > 产品设计 > UI/UE

hdu 5288 OO’s Sequence(2015多校第一场第1题)枚举因子

2015-07-22 16:03 585 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5288

题意:在闭区间[l,r]内有一个数a[i],a[i]不能整除 除去自身以外的其他的数,f(l,r)表示在这区间内a[i]这样的数的个数,,现给你n个数,求所有区间的f(l,r)的和。

思路:对于每个数a[i]求出他的左右侧最靠近他的且是他的因子的位置L、R,并记录,那么对于每个数a[i]都有了他的L,R,而对于每个a[i]在f(l,r)有价值的次数之和就是(i-L+1)*(R-i+1)

代码:

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
#define LL __int64
#define INF 0x3f3f3f3f
const int MAXN=100005;
#define mod 1000000007
int l[MAXN];
int r[MAXN];
int a[MAXN];
int visl[MAXN];
int visr[MAXN];
LL ans;
int main()
{
int n,i,j;
while(~scanf("%d",&n))
{
memset(visl,0,sizeof(visl));
memset(visr,0,sizeof(visr));
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
l[i]=1;
r[i]=n;
}
for(i=1;i<=n;i++)
{
for(j=a[i];j<=10000;j+=a[i])
{
if(visr[j]&&r[visr[j]]==n)
r[visr[j]]=i-1;
}
visr[a[i]]=i;
}
for(i=n;i>0;i--)
{
for(j=a[i];j<=10000;j+=a[i])
{
if(visl[j]&&l[visl[j]]==1)
l[visl[j]]=i+1;
}
visl[a[i]]=i;
}
ans=0;
for(i=1;i<=n;i++)
{
//printf("%d %d\n",l[i],r[i]);
ans+=(LL)(i+1-l[i])*(r[i]-i+1);
ans%=mod;
}
printf("%I64d\n",ans%mod);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: