Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 8835 | Accepted: 4362 |
Description
Input
Output
Sample Input
37 29 41 43 47
Sample Output
654
Source
这种问一个等式有几种答案的一般都是前几个算一下然后hash,再算后几个,像今年有场多校的一题。用map会超时,要手动hash离散化,查找用二分。
代码
#include <stdio.h> #include <algorithm> using namespace std; int a[10]; int hash[1000005]; int now[1000005]; int sum[1000005]; int upp; int Count(int x,int y,int z) { return a[0]*x*x*x+a[1]*y*y*y+a[2]*z*z*z; } int Find(int t) { int l,r,mid; l=0; r=upp-1; while(l<=r) { mid=(l+r)/2; if (hash[mid]==t) return sum[mid]; if (hash[mid]<t) l=mid+1; else r=mid-1; } return 0; } int main() { int i,j,n,ans,k,tag,up,num,val; while(scanf("%d",&a[0])!=EOF) { up=0; for (i=1;i<5;i++) { scanf("%d",&a[i]); } for (i=-50;i<=50;i++) { if (i==0) continue; for (j=-50;j<=50;j++) { if (j==0) continue; for (k=-50;k<=50;k++) { if (k==0) continue; now[up++]=Count(i,j,k); } } } sort(now,now+up); upp=0; for (i=0;i<up;i++) { if (i==0) { num=1; val=now[0]; continue; } if (val!=now[i]) { hash[upp]=val; sum[upp++]=num; num=1; val=now[i]; } else num++; } hash[upp]=val; sum[upp++]=num; ans=0; for (i=-50;i<=50;i++) { if (i==0) continue; for (j=-50;j<=50;j++) { if (j==0) continue; tag=i*i*i*a[3]+j*j*j*a[4]; tag=-tag; ans+=Find(tag); } } printf("%d\n",ans); } return 0; }