方程的解数

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

.
.
.
.
.
.
分析
通过枚举3个未知数的值来找到答案
前一半式子的值 S 可以确定,这时只要枚举后3 个数的值,检查他们的和是否等于 -S 即可
需要预先算出 1 到 150 的各个幂次的值
用哈希表判断某个元素是否在给定集合中
.
.
.
.
.
程序:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int p=5000001;
int h[5000001][2],a[7],b[7],n,m,mid;
long long ans;

int ksm(int x,int y)
{
	int ans=1;
	while (y)
	{
		if(y&1) ans*=x;
		x*=x;
		y=y>>1;
	}
	return ans;
}

int find(int x)
{
	int s=abs(x);
	int y=s%p;
	while (h[y][0]&&h[y][0]!=x) 
	{
		y++;
		y=y%p;
	}
	return y;
}

void dfs1(int dep,int sum)
{
	if (dep==mid)
	{
		for (int i=1;i<=m;i++)
	 	{
	 		int x=sum+a[dep]*ksm(i,b[dep]);
	 		int y=find(x);
			h[y][0]=x;
			h[y][1]++;
	 	}
	} else
	{
		for (int i=1;i<=m;i++)
	 		dfs1(dep+1,sum+a[dep]*ksm(i,b[dep]));
	}
}

void dfs2(int dep,int sum)
{
	if (dep==n)
	{
		for (int i=1;i<=m;i++)
	 	{
	 		long long t=-1*(sum+a[dep]*ksm(i,b[dep]));
	 	 	if (h[find(t)][0]==t) ans+=h[find(t)][1];
	 	}
	} else
	for (int i=1;i<=m;i++)
		dfs2(dep+1,sum+a[dep]*ksm(i,b[dep]));
}

int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
		scanf("%d%d",&a[i],&b[i]);
	mid=n>>1;
	if(n==1)
	if (!a[1]) printf("%d",m); else printf("0");
	if (n!=1)
	 {
	 	dfs1(1,0);
	 	dfs2(mid+1,0);
	 	printf("%lld",ans);
	 }
	 return 0;
}
原文地址:https://www.cnblogs.com/YYC-0304/p/10292789.html