poj 1186 方程的解数 (hash+双向dfs)

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



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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值