题目:
题意:
就是某人自己写了个方程式,结果不知道怎么算(尴尬!)现在求我们来帮助这个逗比来算出每个未知数的值。
分析:
看完题目,小编马上意识到,模拟是跑不了的了。但是如果只是单纯的模拟,那么时间复杂度就是:150^6(11390625000000)。美滋滋……但既然小编做出来了,那么就说明还有办法去算短时间,那么我们就引用初一的知识:移项。将等号两边的未知数的数量尽量均分,把时间复杂度变成:150^3(3375000)。
把题目分析到这里,我们就很好解决了,可以用两个过程(bfs1,bfs2)。bfs1用来求出等号左边未知数可能的值的和;bfs2用来求出等号右边未知数可能的值的和,每求出一次,我们就可以进行一次判断,若等式成立,那么统计变量+1。(最好用bfs,避免开过大的数组范围)
而对于效率,我们在算某个未知数的值的幂的时候可以使用快速幂。在判断等式是否成立时,可采用哈希表进行判定。
具体实现的想法在代码中:
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
inline LL read()
{
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9') {if(s=='-') f=-1;s=getchar();}
while(s>='0'&&s<='9') {d=d*10+s-'0';s=getchar();}
return d*f;
}
int n,m,a[4000037],b[4000037],h[4000037][2],ans;
int ksm(int x,int y)
{
int s=1;
while(y>0)
{
if(y%2!=0) s*=x;
x*=x;
y/=2;
}
return s;
}
int locate(int x)
{
int wz=abs(x)%4000037;
while(h[wz][0]!=0&&h[wz][0]!=x)
wz++,wz%=4000037;
return wz;
}
void in(int x)
{
h[locate(x)][0]=x;
h[locate(x)][1]++;
return;
}
void bfs1(int x,int y)
{
if(x==n/2)
for(int i=1;i<=m;i++)
in(y+a[x]*ksm(i,b[x]));
else
for(int i=1;i<=m;i++)
bfs1(x+1,y+a[x]*ksm(i,b[x]));
return;
}
void bfs2(int x,int y)
{
int t;
if(x==n)
for(int i=1;i<=m;i++)
{
t=-1*(y+a[x]*ksm(i,b[x]));
if(h[locate(t)][0]==t) ans+=h[locate(t)][1];
}
else
for(int i=1;i<=m;i++)
bfs2(x+1,y+a[x]*ksm(i,b[x]));
return;
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
a[i]=read(),b[i]=read();
if(n==1)
{
if(a[1]==0) printf("%d",m);
else puts("0");
return 0;
}
bfs1(1,0);
bfs2(n/2+1,0);
printf("%d",ans);
return 0;
}