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
扫描二维码关注公众号,回复: 4711505 查看本文章

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 }

猜你喜欢

转载自www.cnblogs.com/zjzjzj/p/10199745.html