SSLOJ 1127 方程的解数
题目
Description
Input
第1行包含一个整数n。第2行包含一个整数M。第3行到第n+2行,每行包含两个整数,分别表示ki和pi。两个整数之间用一个空格隔开。第3行的数据对应i=1,第n+2行的数据对应i=n。
Output
仅一行,包含一个整数,表示方程的整数解的个数。
Sample Input
3
150
1 2
-1 2
1 2
Sample Output
178
分析
因为数据是150^6光搜索就爆了
所以要折半搜索,就是分开两半分别搜索
因为 a..+b..=0 所以 a...=-b...
hash就可以节省很多时间
代码
1 #include<iostream> 2 #include<cmath> 3 #include<cstdio> 4 #define N 4000037 5 #define hash(x) (x)%N 6 #define f(i,a,b) for (int i=a;i<=b;i++) 7 using namespace std; 8 long long a[7],b[7]; 9 int h[N][2]; 10 long long n,m; 11 long long ans1=0; 12 int mid; 13 int find(int x) 14 { 15 int xx=abs(x); 16 int k=hash(xx),i=0; 17 while(i<N&&h[(k+i)%N][0]!=x&&h[(k+i)%N][0]!=0) 18 i++; 19 return (k+i)%N; 20 } 21 void tp() 22 { 23 if(n==1) 24 if(!a[1]) cout<<m; 25 else cout<<0; 26 } 27 int ksm(int a,int b) 28 { 29 long long ans=1; 30 while (b) 31 { 32 if (b&1) ans*=a; 33 a*=a; 34 b>>=1; 35 } 36 return ans; 37 } 38 bool pd(int x)//判断x这个元素是否在hash表内 39 { 40 return h[find(x)][0]==x; 41 } 42 43 void dfs1(int lev,long long sum) 44 { 45 if (lev>mid) 46 { 47 int wz=find(sum); 48 h[wz][1]++; 49 h[wz][0]=sum; 50 return; 51 } 52 else 53 f(i,1,m) 54 dfs1(lev+1,sum+a[lev]*ksm(i,b[lev])); 55 } 56 void dfs2(int lev,long long sum) 57 { 58 if(lev>n) 59 { 60 long long t=-1*sum; 61 int wz=find(t); 62 if(pd(t)) ans1+=h[wz][1]; 63 } 64 else 65 f(i,1,m) 66 dfs2(lev+1,sum+a[lev]*ksm(i,b[lev])); 67 } 68 int main () 69 { 70 71 scanf("%d %d",&n,&m); 72 for (int i=1;i<=n;i++) 73 scanf("%d %d",&a[i],&b[i]); 74 tp(); 75 mid=n/2; 76 if (n!=1) 77 { 78 dfs1(1,0); 79 dfs2(mid+1,0); 80 printf("%lld",ans1); 81 } 82 83 }
为何要逼自己长大,去闯不该闯的荒唐