方程的解数
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;
}