absi2011
一个新的开始吧w 希望这一次能如我所愿w
随笔 - 27,  文章 - 0,  评论 - 4

设f(x)为a2 + b2 = x2的整数解的个数(可以是负数)

BZOJ 1041: 求f(x)

PE 233: 求n<=1011中有多少个数f(x)=420

==============================

首先观察并思考

我们首先去掉a/b=x/-x 的四个解,然后除以4(考虑a,b都是正数的情况)

再不妨假设a<b,那么这就是g(x)

f(x)=8*g(x)+4

我打了一个表,其中发现:

g(5)=1 g(25)=2 g(125)=3 g(625)=4 .....

g(13)=1 g(17)=1

g(65)=4 g(85)=4

1105 = 5*13*17

g(1105)=13 (这个真的很震撼,当时推了好久没看出来为啥是13)

我尝试了g(13*25)=7

g(13*125)=10

g(13*625)=13

(再大表就跑不动了)

g(25*169)=12

最后猜了

g(a*b) = g(a) + g(b) + 2*g(a)*g(b)

(gcd(a,b)=1)

以及g(%4=1的质数)=1

g(%4=2/3的质数)=0

g(pk)=k*g(p)

所以我们要问有几个x

g(x)=52

我们定义a (+) b表示  a+b+2*a*b

那么

52 = 1 (+) 2 (+) 3

     = 10 (+) 2

     = 7 (+) 3

一共有3个可行的分配方案,直接暴力就行了

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<time.h>
#include<vector>
#include<bitset>
#include<memory>
#include<utility>
#include<fstream>
#include<stdio.h>
#include<sstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
/*
int f[10005];
//const int five_tweleve=244140625;
void dfs(int x)
{
    int i,j;
    for (i=1;i<=x;i++)
    {
        for (j=i;j<=x;j++)
        {
            if ((i+j+i*j+i*j==x))
            {
                printf("%d %d %d\n",i,j,x);
                dfs(i);
                dfs(j);
            }
        }
    }
}
bool isprime(int x)
{
    int i;
    for (i=2;i*i<=x;i++)
    {
        if (x%i==0) return false;
    }
    return true;
}
*/
bool prime[10000005];
bool unnum[10000005];
long long ssum[10000005];
const long long max_n=100000000000ll;
long long power(int x,int y)
{
    long long p=1;
    int i;
    for (i=0;i<y;i++)
    {
        p*=x;
        if (p>max_n) return p;
    }
    return p;
}
vector<int> v;
int main()
{
    freopen("output.txt","w",stdout);
    int i;
    memset(prime,true,sizeof(prime));
    prime[1]=false;
    const int n=10000000;
    for (i=2;i<=10000;i++)
    {
        if (prime[i])
        {
            int j;
            for (j=i*i;j<=n;j+=i)
            {
                prime[j]=false;
            }
        }
    }
    for (i=5;i<=n;i+=4)
    {
        if (prime[i])
        {
            v.push_back(i);
            int j;
            for (j=i;j<=n;j+=i)
            {
                unnum[j]=true;
            }
        }
    }
    for (i=1;i<=n;i++)
    {
        ssum[i]=ssum[i-1];
        if (!unnum[i]) ssum[i]+=i;
    }
    unsigned long long ans=0;
    long long p=1;
    for (i=0;i<(int)v.size();i++)
    {
        p=power(v[i],7);
        if (p*5*5*5>max_n) break;
        int j;
        for (j=0;j<(int)v.size();j++)
        {
            if (i==j) continue;
            long long k=power(v[j],3);
            if (p*k>max_n) break;
            ans+=ssum[max_n/(p*k)]*p*k;
        }
    }
    for (i=0;i<(int)v.size();i++)
    {
        p=power(v[i],10);
        if (p*5*5>max_n) break;
        int j;
        for (j=0;j<(int)v.size();j++)
        {
            if (i==j) continue;
            long long k=power(v[j],2);
            if (p*k>max_n) break;
            ans+=ssum[max_n/(p*k)]*p*k;
        }
    }
    for (i=0;i<(int)v.size();i++)
    {
        p=power(v[i],3);
        if (p*5*5*5>max_n) break;
        int j;
        for (j=0;j<(int)v.size();j++)
        {
            if (i==j) continue;
            long long k=power(v[j],2);
            if (p*k*5>max_n) break;
            int l;
            for (l=0;l<(int)v.size();l++)
            {
                if (l==j) continue;
                if (l==i) continue;
                long long t=v[l];
                if (p*k*t>max_n) break;
                ans+=ssum[max_n/(p*k*t)]*p*k*t;
            }
        }
    }
    cout<<ans<<endl;
    //dfs(52);
    //1 + 2 + 3 = 52
    //2 + 10 = 52 (13^10 overflow)
    //3 + 7 = 52
    /*
    int i;
    //int n=100000000000ll/five_tweleve;
    int n=10000;
    int ans=0;
    for (i=2;i<=n;i++)
    {
        int j;
        f[i]=0;
        if (!isprime(i)) continue;
        for (j=1;j<i;j++)
        {
            int t=sqrt(i*i-j*j);
            if (t*t+j*j==i*i)
            {
                f[i]++;
                printf("%d %d %d\n",t,j,i);
            }
        }
        printf("%d %d i%%4 = %d\n",i,f[i]/2,i%4);
        if ((f[i]==(420-4)/4/13)&&(i%5!=0))
        {
            //ans+=i;
        }
    }
    //cout<<ans*(long long)five_tweleve<<endl;
    */
    return 0;
}

附:BZOJ 1041:

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<time.h>
#include<vector>
#include<bitset>
#include<memory>
#include<utility>
#include<fstream>
#include<stdio.h>
#include<sstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
int adds(int x,int y)
{
    return x+y+x*y+x*y;
}
int main()
{
    int n;
    cin>>n;
    int i;
    int ans=0;
    for (i=2;i*i<=n;i++)
    {
        if (n%i==0)
        {
            int now=0;
            for (;n%i==0;)
            {
                now++;
                n/=i;
            }
            if (i%4==1)
            {
                ans=adds(ans,now);
            }
        }
    }
    if ((n!=1)&&(n%4==1))
    {
        ans=adds(ans,1);
    }
    printf("%d\n",ans*8+4);
    //system("pause");
    return 0;
}

  

posted on 2018-06-27 19:50  absi2011  阅读(52)  评论(0编辑  收藏