题目地址:click here~
题目意思:
要你求出x^n-1的最简多项式
解题思路:
官方解题报告:
手工或写暴力程序计算较小的n,可观察到(x^n-1)的分解式中含有(x^ni-1)的分解式。
其中ni是n的约数(n本身除外)。
除了(x^ni-1)的分解式外,(x^n-1)还含有一项自己独有的分解式,记为P(n)。
于是我们就得到了(x^n-1)的分解:(x^n-1)=P(n1)P(n2)P(n3)...P(n)
其中,n1,n2,n3,...是n的约数(n本身除外)。
从n=1算起,P(1)=x-1。
对于所有的n,P(n)均可通过前面的结果算得:P(n)=(x^n-1)/P(n1)/P(n2)/P(n3)/...
最后对P(n1)P(n2)P(n3)...P(n)排序即可。
时间复杂度:O(n^2*logn)。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
using namespace std;
const int maxn = 1111;
struct node
{
int n;
int value[maxn];
void print(int cishu,int v,bool is_1)
{
if(v==0)
return;
if(is_1)
{
if(v>0)
printf("+");
else
printf("-");
}
if(cishu==0)
{
printf("1");
return;
}
else
{
if(v!=1 && v!=-1)
{
printf("%d",abs(v));
}
printf("x");
if(cishu>1)
printf("^%d",cishu);
return;
}
}
void out()
{
print(n,value[n],false);
for(int i=n-1;i>=0;i--)
print(i,value[i],true);
}
};
bool operator < (const node &a,const node &b)
{
if(a.n == b.n)
{
for(int i=a.n;i>=0;i--)
{
if(abs(a.value[i]) == abs(b.value[i]))
{
if(a.value[i] != b.value[i])
return a.value[i]<b.value[i];
}
else
return abs(a.value[i]) < abs(b.value[i]);
}
}
return a.n<b.n;
}
node operator / (node a,const node &b)
{
node c;
c.n = a.n-b.n;
for(int i=c.n;i>=0;i--)
{
if(a.n-b.n<i)
{
c.value[i] = 0;
continue;
}
c.value[i] = a.value[a.n]/b.value[b.n];
int d = a.n-b.n;
a.n = a.n-b.n;
for(int j=b.n;j>=0;j--)
{
a.value[j+d] -= b.value[j]*c.value[i];
if(a.value[j+d])
a.n = max(a.n,j+d);
}
}
return c;
}
node tmp[maxn];
node goal[maxn];
bool vis[maxn];
int alln;
void solve(int n)
{
alln = 0;
for(int i=1;i<=n;i++)
{
if(n%i==0)
{
if(!vis[i])
{
vis[i] = true;
tmp[i].n = i;
tmp[i].value[i] = 1;
tmp[i].value[0] = -1;
for(int j=1;j<i;j++)
{
if(i%j==0)
tmp[i] = tmp[i]/tmp[j];
}
}
goal[alln++] = tmp[i];
}
}
sort(goal,goal+alln);
}
int main()
{
memset(vis,false,sizeof(vis));
int n;
while(~scanf("%d",&n) && n)
{
if(n==1)
{
printf("x-1\n");
continue;
}
else
{
solve(n);
for(int i=0;i<alln;i++)
{
printf("(");
goal[i].out();
printf(")");
}
printf("\n");
}
}
return 0;
}