Description
已知一個n元高次方程:
其中:x1, x2,...,xn是未知數,k1,k2,...,kn是系數,p1,p2,...pn是指數。且方程中的所有數均為整數。
假設未知數1 <= xi <= M, i=1,,,n,求這個方程的整數解的個數。
1 <= n <= 6;1 <= M <= 150。
方程的整數解的個數小于2 31。
★本題中,指數Pi(i=1,2,...,n)均為正整數。
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
Source
Noi 01
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long ll;
const int maxn=5000001;
struct hash
{
int val;
int count;
}hashset[maxn];
int ki[10],pi[10];
int n,m,sum,mid;
int gethash(int k)
{
int x=((k%maxn)+maxn)%maxn;
while(hashset[x].count>0&&hashset[x].val!=k)
{
x=(x+1)%maxn;
}
return x;
}
int quickmod(int a,int b)
{
int ans=1;
while(b)
{
if(b&1)
ans=ans*a;
b>>=1;
a=a*a;
}
return ans;
}
void dfs1(int i, int k)
{
if(i==mid)
{
int pos=gethash(k);
hashset[pos].val=k;
hashset[pos].count++;
return ;
}
for(int u=1;u<=m;u++)
dfs1(i+1,k+ki[i+1]*quickmod(u,pi[i+1]));
}
void dfs2(int i,int k)
{
if(i==(mid+1))
{
int pos=gethash(k);
sum+=hashset[pos].count;
return ;
}
for(int u=1;u<=m;u++)
dfs2(i-1,k-ki[i-1]*quickmod(u,pi[i-1]));
}
int main()
{
int i;
while(~scanf("%d%d",&n,&m))
{
mid=n/2;
sum=0;
for(i=1;i<=n;i++)
scanf("%d%d",&ki[i],&pi[i]);
dfs1(0,0);
dfs2(n+1,0);
printf("%d\n",sum);
}
return 0;
}