设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; }