sgu 491 Game for Little Johnny

http://acm.sgu.ru/problem.php?contest=0&problem=491

 

给一个N,求有多少对A和B(1 ≤ A < B ≤ N),让方程Ax+By=N有自然数解。
3091MS:

#include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

#define MAXN 100001

vector<int> fac[MAXN];

int tmp[MAXN*100];

void get_fac(int n)
{
    if(fac[n].size()>0) return;
    int i,num=0;
    for(i=1; i*i<=n; i++)
    {
        if(n%i==0)
        {
            tmp[num++] = i;
            tmp[num++] = n/i;
     //       printf("n=%d i=%d\n",n,i);
        }
    }
    sort(tmp,tmp+num);
    fac[n].push_back(tmp[0]);
    for(i=1; i<num; i++)
    {
        if(tmp[i]!=tmp[i-1]) fac[n].push_back(tmp[i]);
    }

}

void solve(const int n)
{
    int i,a,ax,b,by,num,ans=0;
    for(i=1; i<=n; i++) get_fac(i);
    for(a=1; a<n; a++)
    {
        num = 0;
        for(ax=a; ax<n; ax+=a)
        {
            by = n - ax;
            for(vector<int>::reverse_iterator rit = fac[by].rbegin(); rit != fac[by].rend(); rit++)
            {
                b = *rit;
                if(b > a) tmp[num++] = b;
                else break;
            }
        }
        if(!num) continue;
        sort(tmp,tmp+num);
        ans++;
        for(int t=1; t<num; t++)
            if(tmp[t]!=tmp[t-1]) ans++;
    }
    printf("%d\n",ans);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("tdata.txt","r",stdin);
#endif
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        solve(n);
    }
    return 0;
}

posted @ 2010-09-12 23:46  菜到不得鸟  阅读(232)  评论(0)    收藏  举报