zoj 1186 方程的解数

来源:互联网 发布:潍坊全影网络是传销吗 编辑:程序博客网 时间:2024/04/30 17:20
方程的解数
Time Limit: 15000MS Memory Limit: 128000KTotal Submissions: 7234 Accepted: 2491Case Time Limit: 5000MS

Description

已知一个n元高次方程: 
 
其中:x1, x2,...,xn是未知数,k1,k2,...,kn是系数,p1,p2,...pn是指数。且方程中的所有数均为整数。 
假设未知数1 <= xi <= M, i=1,,,n,求这个方程的整数解的个数。 
1 <= n <= 6;1 <= M <= 150。 
 
方程的整数解的个数小于231。 
★本题中,指数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

31501  2-1  21  2

Sample Output

178
解法:这道题直接枚举时间复杂度是O(M^6)会超时,我们可以先枚举前三个值,记录在hash表里,然后枚举后三个数的值,如果
它们的和为0即可。
    const  p=4000037;  maxn=150;var  a,b:array[1..6] of longint;  h:array[0..p,1..2] of longint;  mi:array[1..maxn,1..30] of longint;  n,m:longint;  ans:int64;procedure init;var  i,j:longint;begin  readln(n);  readln(m);  for i:=1 to n do    readln(a[i],b[i]);  for i:=1 to 30 do    mi[1,i]:=1;  for i:=2 to m do    begin      mi[i,1]:=i;      for j:=2 to trunc(ln(maxlongint)/ln(i)) do        mi[i,j]:=mi[i,j-1]*i;    end;end;procedure special;var  i:longint;begin  if n=1 then    if a[1]=0      then writeln(m)      else writeln(0);end;function hash(x:longint):longint;var  i:longint;begin  hash:=abs(x) mod p;  i:=0;  while (h[(hash+i) mod p,1]<>0) and (h[(hash+i) mod p,1]<>x) do inc(i);  hash:=(hash+i) mod p;end;procedure insert(x:longint);var  tmp:longint;begin  tmp:=hash(x);  h[tmp,1]:=x;  inc(h[tmp,2]);end;procedure dfs1(x,s:longint);var  i:longint;begin  if x=n div 2 then    begin      for i:=1 to m do        insert(s+a[x]*mi[i,b[x]]);    end    else      for i:=1 to m do        dfs1(x+1,s+a[x]*mi[i,b[x]]);end;procedure dfs2(x,s:longint);var  i:longint;  t,posi:int64;begin  if x=n then    for i:=1 to m do      begin        t:=-1*(s+a[x]*mi[i,b[x]]);        posi:=hash(t);        if h[posi,1]=t then inc(ans,h[posi,2]);      end    else      for i:=1 to m do        dfs2(x+1,s+a[x]*mi[i,b[x]]);end;begin  init;  special;  if n<>1 then    begin      dfs1(1,0);      dfs2(n div 2+1,0);      writeln(ans);    end;end.
0 0