題目:
已知一個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 }