Mutiple HDU - 5211(筛法,有技巧的枚举)

WLD likes playing with a sequence a[1…N]. One day he is playing with a sequence of N integers. For every index i, WLD wants to find the smallest index F(i) ( if exists ), that i<F(i)≤n, and aF(i) mod ai = 0. If there is no such an index F(i), we set F(i) as 0.
Input
There are Multiple Cases.(At MOST 10)

For each case:

The first line contains one integers N(1≤N≤10000).

The second line contains N integers a1,a2,…,aN(1≤ai≤10000),denoting the sequence WLD plays with. You can assume that all ai is distinct.
Output
For each case:

Print one integer.It denotes the sum of all F(i) for all 1≤i<n
Sample Input
4
1 3 2 4
Sample Output
6

Hint
F(1)=2
F(2)=0
F(3)=4
F(4)=0

题意:
对于a[i],寻找 i < j ≤ n 使得 a[j] % a[i] = 0。也即F[i] = j。如果不存在,则 F[i] = 0。
求∑F[i].
思路:
正解是筛法。从后往前,标记之前出现过的a[i],再枚举当前a[i]的倍数,看是否出现过,出现过则取最小值。
不过本题数据水,暴力10亿复杂度也过了2333.

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int INF = 0x3f3f3f3f;
int a[10005];
int mp[10005];

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int ans = 0,mx = 0;
        for(int i = 1;i <= n;i++)
        {
            scanf("%d",&a[i]);
            mx = max(mx,a[i]);
        }
        
        memset(mp,INF,sizeof(mp));
        for(int i = n;i >= 1;i--)
        {
            int mi = INF;
            for(int j = a[i];j <= 10001;j+= a[i])
            {
                if(mp[j] != INF)
                {
                    mi = min(mi,mp[j]);
                }
            }
            if(mi != INF)ans += mi;
            mp[a[i]] = i;
        }
        printf("%d\n",ans);
    }
    return 0;
}

发布了628 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/104008613
今日推荐