题意非常easy:
对于长度为n的数。做n-1遍。生成的新数列:
b1=a2-a1 b2=a3-a2 b3=a4-a3
c1=b2-b1 c2=b3-b2
ans=c2-c1
最后推出公式: 为n所在行的杨辉三角
对于例子:
3
1 2 3
ans=1*1-2*2+1*3=0
4
1 5 7 2
ans=-1*1+3*5-3*7+1*2=-5
求杨辉三角每一个数的时候能够优化一下,后一个数由前一个各乘除一次就好了
JAVA用大数秒A。
。
。
BUT 不会JAVA - -#
蛋疼用C++模拟大数。。
#include "stdio.h" #include "string.h" int a[3010]; __int64 mark[3010],ans[3010],c[3010]; int Max(int a,int b) { if (a<b) return b;else return a; } void make_mul(int x) { int i; for (i=1;i<=mark[0];i++) mark[i]*=x; for (i=1;i<=mark[0];i++) { mark[i+1]+=mark[i]/1000000; mark[i]%=1000000; } while (mark[mark[0]+1]!=0) { mark[0]++; mark[mark[0]+1]=mark[mark[0]]/1000000; mark[mark[0]]%=1000000; } } void make_div(int x) { int i; for (i=mark[0];i>=2;i--) { mark[i-1]+=(mark[i]%x)*1000000; mark[i]/=x; } mark[1]/=x; while (mark[mark[0]]==0) mark[0]--; } void make_add() { int i,op; if (ans[0]>0) { for (i=1;i<=mark[0];i++) { ans[i]+=mark[i]; ans[i+1]+=ans[i]/1000000; ans[i]%=1000000; } while (ans[ans[0]+1]!=0) { ans[0]++; ans[ans[0]+1]=ans[ans[0]]/1000000; ans[ans[0]]%=1000000; } return ; } else { if (-ans[0]>mark[0]) op=-1; else if (-ans[0]<mark[0]) op=1; else { for (i=mark[0];i>=1;i--) if (mark[i]>ans[i]) { op=1;break;} else if (mark[i]<ans[i]) { op=-1; break;} if (i==0) { memset(ans,0,sizeof(ans)); ans[0]=1; return ; } } if (op==1) { for (i=1;i<=mark[0];i++) { ans[i]=mark[i]-ans[i]; if (ans[i]<0) { mark[i+1]--; ans[i]+=1000000; } } ans[0]=-ans[0]; while (ans[ans[0]]==0) ans[0]--; } else { for (i=1;i<=-ans[0];i++) { ans[i]=ans[i]-mark[i]; if (ans[i]<0) { ans[i+1]--; ans[i]+=1000000; } } while (ans[-ans[0]]==0) ans[0]++; } } } void make_red() { int i,op; if (ans[0]<0) { for (i=1;i<=mark[0];i++) { ans[i]+=mark[i]; ans[i+1]+=ans[i]/1000000; ans[i]%=1000000; } while (ans[-ans[0]+1]!=0) { ans[0]--; ans[-ans[0]+1]=ans[-ans[0]]/1000000; ans[-ans[0]]%=1000000; } return ; } else { if (ans[0]>mark[0]) op=1; else if (ans[0]<mark[0]) op=-1; else { for (i=mark[0];i>=1;i--) if (mark[i]>ans[i]) { op=-1;break;} else if (mark[i]<ans[i]) { op=1; break;} if (i==0) { memset(ans,0,sizeof(ans)); ans[0]=1; return ; } } if (op==1) { for (i=1;i<=mark[0];i++) { ans[i]=ans[i]-mark[i]; if (ans[i]<0) { ans[i+1]--; ans[i]+=1000000; } } while (ans[ans[0]]==0) ans[0]--; } else { for (i=1;i<=mark[0];i++) { ans[i]=mark[i]-ans[i]; if (ans[i]<0) { mark[i+1]--; ans[i]+=1000000; } } ans[0]=mark[0]; while (ans[ans[0]]==0) ans[0]--; ans[0]=-ans[0]; } } } int main() { int t,n,i,x,y,j,m,op; scanf("%d",&t); while (t--) { scanf("%d",&n); for (i=1;i<=n;i++) scanf("%d",&a[i]); memset(ans,0,sizeof(ans)); ans[0]=1; if (i==1) { printf("%d ",a[1]); continue; } memset(mark,0,sizeof(mark)); mark[0]=1; mark[1]=1; if (n%2==1) ans[1]=a[1]; else ans[1]=-a[1]; x=1; y=n-1; for (i=2;i<=n;i++) { make_mul(y); y--; make_div(x); x++; memcpy(c,mark,sizeof(mark)); make_mul(a[i]); if (n%2==1) { if (i%2==1) make_add(); else make_red(); } else { if (i%2==0) make_add(); else make_red(); } memcpy(mark,c,sizeof(c)); } if (ans[0]>0) { printf("%I64d",ans[ans[0]]); for (i=ans[0]-1;i>=1;i--) printf("%06I64d",ans[i]); printf(" "); } else { printf("-"); printf("%I64d",ans[-ans[0]]); for (i=-ans[0]-1;i>=1;i--) printf("%06I64d",ans[i]); printf(" "); } } return 0; }