题解 P2553 【[AHOI2001]多项式乘法】
看到题第一眼,就知道这是个暴力处理多项式然后用fft搞就行了。。。
但是有许多坑点,比如输入字符串中没有'*'就什么也不输出题目就™不能讲清楚吗
因为这个WA了好几次,又因为只有一个数据点,每次都提示输出多了,我也看不了别人代码对一下。。。
最后在网上找了一个博客,试了几组数据都正确并且ta还不能处理没有括号的情况
看到ta的代码中有一行:
if(ppos == std::string::npos) continue;
这是干啥啊大兄弟。。。似乎是判断有没有'*'?
然后加上就过了。。。这种垃圾题还是别出了QAQ
代码:
# include<iostream>
# include<cstring>
# include<cstdio>
# include<cmath>
using namespace std;
const int MAX=1e6+1;
const double Pi=acos(-1.0);
struct complex{
double x,y;
complex(double X=0,double Y=0){x=X,y=Y;}
}a[2][MAX];
int n,m,l,lim=1;
int r[MAX],len[MAX],ans[MAX];
complex operator+ (complex x,complex y)
{
return complex(x.x+y.x,x.y+y.y);
}
complex operator- (complex x,complex y)
{
return complex(x.x-y.x,x.y-y.y);
}
complex operator* (complex x,complex y)
{
return complex(x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x);
}
void fft(complex *A,int tt)
{
for(int i=0;i<lim;++i)
if(i<r[i]) swap(A[i],A[r[i]]);
for(int i=1;i<lim;i<<=1)
{
complex w1(cos(Pi/i),tt*sin(Pi/i));
for(int l=i<<1,j=0;j<lim;j+=l)
{
complex w(1,0);
for(int k=0;k<i;++k,w=w*w1)
{
complex x=A[j+k],y=w*A[j+i+k];
A[j+k]=x+y,A[j+i+k]=x-y;
}
}
}
if(tt==-1)
for(int i=0;i<lim;++i)
A[i].x=(int)(A[i].x/lim+0.5);
}
int main()
{
string s;
while(getline(cin,s))
{
bool fl=0;
int L=s.length(),num=0;
for(int i=0;i<L;++i)
if(s[i]=='*')
{
fl=1;
break;
}
if(!fl) continue;
memset(a,0,sizeof(a));
memset(len,0,sizeof(len));
memset(ans,0,sizeof(ans));
for(int i=0,tt=0;i<L;i+=tt)
{
tt=0;
int x=0;
if(isdigit(s[i]))
{
int j=i;
while(isdigit(s[j])) ++tt,x=x*10+s[j++]-48;
while(s[j]==' ') ++j;
if(s[j]=='a')
{
j+=2,tt+=2;
int y=0;
while(isdigit(s[j])) ++tt,y=y*10+s[j++]-48;
len[num]=max(len[num],y);
a[fl][y].x+=x;
}
else if(s[j]=='+'||s[j]==')'||s[j]=='*'||j==L) a[fl][0].x+=x;
}
if(s[i]=='*'||i+(tt?tt:1)-1==L-1)
{
if(s[i]=='*') ++tt;
if(num>=1)
{
lim=1,l=0;
memset(r,0,sizeof(r));
while(lim<=len[num]+len[num-1]) lim<<=1,++l;
for(int j=0;j<lim;++j)
r[j]=(r[j>>1]>>1)|((j&1)<<(l-1));
fft(a[fl],1),fft(a[fl^1],1);
for(int j=0;j<=lim;++j)
a[fl][j]=a[fl][j]*a[fl^1][j];
fft(a[fl],-1);
for(int j=0;j<=lim;++j)
a[fl][j].y=a[fl^1][j].y=a[fl^1][j].x=0;
len[num]=len[num]+len[num-1];
}
++num,fl^=1;
}
if(!tt) ++tt;
}
bool gg=0;
for(int j=0;j<=len[num]+len[num-1];++j)
{
ans[j]+=a[fl^1][j].x;
if(a[fl^1][j].x!=0) gg=1;
}
if(!gg)
{
printf("0\n");
continue;
}
int Len1=0,Len2=0;
for(int i=0;!ans[i];++i)
++Len1;
Len2=Len1;
for(int i=Len1+1;ans[i]!=0;++i)
++Len2;
if(Len2!=Len1) printf("%da^%d",ans[Len2],Len2);
for(int i=Len2-1;i>Len1;--i)
printf("+%da^%d",ans[i],i);
if(!Len1)
{
if(Len2) printf("+%d\n",ans[0]);
else printf("%d\n",ans[0]);
}
else
{
if(Len2!=Len1) printf("+%da^%d\n",ans[Len1],Len1);
else printf("%da^%d\n",ans[Len1],Len1);
}
}
return 0;
}