方程的解数

                                                                                                                                                                 题目在这里呀

题目:

  已知一个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 } 
View Code

 

转载于:https://www.cnblogs.com/forward777/p/10307615.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值