题目:
已知一个n元高次方程:
其中:x1, x2,...,xn是未知数,k1,k2,...,kn是系数,p1,p2,...pn是指数。且方程中的所有数均为整数。
假设未知数1 <= xi <= M, i=1…n,求这个方程的整数解的个数。
1 <= n <= 6;1 <= M <= 150。
方程的整数解的个数小于2 31(本题中,指数Pi(i=1,2,...,n)均为正整数。)
思路:
最简单的dfs 当然就是枚举每个k,p所对应的x 然后check 更新ans
但是 这一定是会TLE的 因为复杂度是 150的6次方
要注意 Xi X是有下标的 说明是不同的X !
正解是:
把式子分为两个部分 分别dfs求出两个部分的所有可能值
这样子搜索的复杂度就变成150的3次方再*2了
然后排个序 计算出两个式子相加为0的方案数 即 解的总数
我用的是一一匹配的方法 (是我自己取的名字qwq)
好像还可以用map 或者hash完成这一步 但是 我并不会qwq
还可以加快速幂优化一下呀 (今天写快速幂居然写错了) 这里是快速幂
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #define go(i,u,v) for(register int i=u;i<=v;i++) 5 #define M 3375001 6 using namespace std; 7 int read() 8 { 9 int x=0,y=1;char c=getchar(); 10 while(c<'0'||c>'9') {if(c=='-') y=-1;c=getchar();} 11 while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-'0';c=getchar();} 12 return x*y; 13 } 14 int k[10],p[10],n,m,d1[M],d2[M],n1,n2,t1,t2,ans; 15 int ksm(int x,int y) 16 { 17 int s=1; 18 while(y>0) {if(y&1) s*=x;x*=x;y>>=1;} 19 return s; 20 } 21 void dfs1(int now,int sum) 22 { 23 if(now>n1) {d1[++t1]=sum;return ;} 24 go(i,1,m) dfs1(now+1,sum+k[now]*ksm(i,p[now])); 25 } 26 void dfs2(int now,int sum) 27 { 28 if(now>n2) {d2[++t2]=sum;return ;} 29 go(i,1,m) dfs2(now+1,sum+k[now+n1]*ksm(i,p[now+n1])); 30 } 31 void work() 32 { 33 int r=t2; 34 sort(d1+1,d1+t1+1);sort(d2+1,d2+t2+1); 35 go(l,1,t1) { 36 int s1=1,s2=1; 37 while(d1[l]+d2[r]>0&&r>0) r--; 38 if(!r) break ; 39 if(d1[l]+d2[r]!=0) continue ; 40 while(d1[l+1]==d1[l]&&l<t1) s1++,l++; 41 while(d2[r-1]==d2[r]&&r>0) s2++,r--; 42 ans+=s1*s2; 43 } 44 } 45 int main() 46 { 47 n=read();m=read();n1=n/2;n2=(n+1)/2; 48 go(i,1,n) k[i]=read(),p[i]=read(); 49 dfs1(1,0);dfs2(1,0); 50 work();printf("%d",ans); 51 return 0; 52 }