C
根据初中数学知识,恒成立问题考虑未知数x每一项的系数,然后得到(d+1)个等式,根据前两个就可以推出\(s=\frac{b_{d-1}-a_{d-1}}{da_d}\)且\(a_d=b_d\)
但是一直不会用题目给的n个点值求出最高的两项系数(或它们的比值),并且怀疑是否把(d+1)个等式全部用到会更好做,然后两个方向分别搞了半天都没有结果,就下班了。。。
对于题目给点值,只能想到拉格朗日插值,然而并没有发现插值的式子可以暴力转化成和普通式子的系数!直接硬拆就好了,因为只要最高两项系数,很容易分别线性算出。
然后沿着这个思路去算任意项的系数,似乎就可以得到多项式快速插值的算法了!(所以无论是能现场看出插值式子和系数的转化还是学过多项式快速插值都能轻松切掉,无脑+无科技选手被成功区分)
另:怎么还卡scanf啊
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int readfast(){
int x=0,tag=1; char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')tag=-1;
for(; isdigit(c);c=getchar())x=x*10+c-48;
// ungetc(c,stdin);
return x*tag;
}
const int N=5e6+5,P=1e9+7;
void inc(int& x,int y){
x+=y;
if(x>=P) x-=P;
if(x<0) x+=P;
}
int sum(int x,int y){
x+=y;
if(x>=P) x-=P;
if(x<0) x+=P;
return x;
}
void mul(int& x,int y){
x=1ll*x*y%P;
}
int prd(int x,int y){
return 1ll*x*y%P;
}
inline int fpw(int a,int x){
int s=1;
for(;x;x>>=1,a=prd(a,a)) if(x&1) s=prd(s,a);
return s;
}
int inv[N],s[N];
int cnt1(int n,int* a){
int ans=0;
for(int i=0;i<=n;i++){
int u=prd(s[i],s[n-i]);
if((n-i)&1) u=P-u;
inc(ans,prd(u,a[i]));
//cout<<i<<" "<<u<<" "<<ans<<endl;
}
return ans;
}
int cnt(int n){
int s=n;
if(n&1) mul(s,(n+1)>>1);
else s>>=1,mul(s,n+1);
return s;
}
int cnt2(int n,int* a){
int ans=0;
for(int i=0;i<=n;i++){
int u=prd(s[i],s[n-i]);
if((n-i)&1) u=P-u;
int v=sum(cnt(n),P-i);
v=P-v;
inc(ans,prd(prd(u,v),a[i]));
}
return ans;
}
int d,a[N],b[N];
void work(){
cin>>d;
inv[1]=s[0]=s[1]=1;
for(int i=2;i<=d;++i) {
inv[i]=prd((P-P/i),inv[P%i]);
s[i]=prd(s[i-1],inv[i]);
//cout<<i<<" "<<s[i]<<endl;
}
for(int i=0;i<=d;i++) a[i]=readfast();
for(int i=0;i<=d;i++) b[i]=readfast();
int k=cnt1(d,a),x=cnt2(d,a),y=cnt2(d,b);
//cout<<k<<" "<<x<<" "<<y<<endl;
int ans=prd(sum(y,P-x),prd(inv[d],fpw(k,P-2)));
cout<<ans<<endl;
}
int main() {
int T=1; while(T--) work();
return 0;
}