POJ 1186 方程的解数 G++ dfs 快速幂 哈希表 背

#include <iostream>
#include <cstdio> 
#include <cstring>
#define MAX 4444444
using namespace std;
//英语      看博友分析      抄博友程序       dfs       快速幂       哈希表      背 
int k[200];
int p[200];
struct hash{
	int val;
	int c;
}hash_t[MAX];//抄博友程序 
int use[MAX];//抄博友程序 
int ans;

int Hash(int x)//背 
{
	int t=x;
	while(t>=MAX)//抄博友程序 
	{
		t=t-MAX;
	}
	while(t<0)
	{
		t=t+MAX;
	}
	while(use[t] && hash_t[t].val!=x)
	{
		t++;
		if(t>=MAX)//
		{
			t=MAX-t;
		}
	}
	return t;
}
int insert_hash(int x)//背 
{
	int t=Hash(x);
	hash_t[t].c++;
	hash_t[t].val=x;
	//cout<<t<<" "<<hx[t].c<<" "<<x<<endl;
	use[t]=1; 
}
int getpow(int x, int p)//背 
{
	int jg=1;
	while(p)
	{
		if(p&1)
		{
			jg=jg*x;
		}	
		p=p>>1;
		x=x*x;	
	}
	return jg;
}
/*
int Hash(int s){
    int temp = s;
    while (temp >= MAX) temp -= MAX;
    while (temp < 0) temp += MAX;
    while(use[temp] && hash_t[temp].val != s){
        temp ++;
        if (temp >= MAX){
            temp -= MAX;
        }
    }
    return temp;
}
void insert_hash(int s){
    int pos = Hash(s);
    hash_t[pos].val = s;
    hash_t[pos].c++;
    use[pos] = 1;
}

int getpow(int x, int p) {
    int tmp = 1;
    while (p) {
        if (p&1)
            tmp *= x;
        x *= x;
        p >>= 1;
    }
    return tmp;
}*/
int n,m;
int mid;
void left_ser(int x, int jg)
{
	//cout<<x<<" "<<jg<<endl;
	if(x==mid)
	{
		insert_hash(jg);
		return; 
	}
	for(int i=1;i<=m;i++)//背 
	{
		left_ser(x+1,jg+k[x]*getpow(i,p[x]));
	}
	
} 
void right_ser(int x, int jg)
{
	//cout<<x<<" "<<jg<<endl;
	if(x==n)
	{
		jg=-jg;
		int t=Hash(jg);
		//cout<<jg<<" "<<t<<endl;
		if(hash_t[t].val==jg)
		{
			//cout<<hx[t].val<<" "<<hx[t].c<<endl;
			ans+=hash_t[t].c;
		}
		return;
	}
	for(int i=1;i<=m;i++)
	{
		right_ser(x+1,jg+k[x]*getpow(i,p[x]));
	}
}
int main()
{
	//cout<<getpow(2,10)<<endl;
	cin>>n;
	cin>>m;
	for(int i=0;i<n;i++)
	{
		cin>>k[i]>>p[i];
	}
	mid=n/2;
	left_ser(0,0);
	//cout<<endl;
	right_ser(mid,0);
	cout<<ans<<endl;
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值