Mutiple
Accepts: 476
Submissions: 1025
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
wld有一个序列 a[1..n] , 对于每个 1≤i<n , 他希望你求出一个最小的 j (以后用记号 F(i) 表示),满足 i<j≤n , 使 aj 为 ai 的倍数(即 aj mod ai =0),若不存在这样的 j ,那么此时令 F(i) = 0 保证 1≤n≤10000,1≤ai≤10000 对于任意 1≤i≤n , 且对于任意 1≤i,j≤n(i!=j) ,满足 ai != aj
输入描述
多组数据(最多 10 组) 对于每组数据: 第一行:一个数 n 表示数的个数 接下来一行: n 个数,依次为 a1,a2,…,an
输出描述
对于每组数据: 输出 F(i) 之和(对于 1≤i<n )
输入样例
4 1 3 2 4
输出样例
6
Hint
F(1)=2 F(2)=0 F(3)=4 F(4)=0
从右向左查看序列 维护一个数组 p[1..10000] 表示该数上一次出现的位置 遇到一个数就暴力查看它的所有倍数,取最小值即可 时间复杂度为 O(n/1+n/2+…+n/n)=O(nlogn)
#include <iostream>
#include <string.h>
using namespace std;
int a[10010],b[10010];
int n,tmp;
int main()
{
while(cin>>n)
{
memset(b,0,sizeof(b));
long long ans=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=n;i>=1;i--)
{
b[a[i]]=i;
tmp=10001;
for(int j=2;j*a[i]<=10000;j++)
{
if(b[j*a[i]]!=0&&b[j*a[i]]<tmp)
tmp=b[j*a[i]];
}
if(tmp!=10001) ans+=tmp;
}
cout<<ans<<endl;
}
return 0;
}
最近做题感觉好多都是从后往前搞的【 !!