Avito Cool Challenge 2018 :E. Missing Numbers
E. Missing Numbers
题目链接:https://codeforces.com/contest/1081/problem/E
题意:
现在有n个数(n为偶数),但只给出a2,a4....an的信息,要求你求出a1,a2....an。
假设前n项的和为Sn,那么满足S1,S2....Sn都为平方项。
题解:
假设S1=a^2,S2=b^2,S3=c^2,S4=d^2,因为我们已知a2,a4,所以得出a2=S2-S1=b^2-a^2,a4=d^2-c^2。
我们可以根据我们设的未知数推出a1=a^2,a3=c^2-b^2。
最后我们将这个推广可以推出a1,a3....an-1的表达式可以根据a0,a2...an得出,这里我们令a0=0。
现在的任务就是找每个数的因子,因为b^2-a^2=(b+a)*(b-a)。这里我们直接预处理一下就好了~
然后我们维护一下之前那个数的b^2(较大平方项),在找当前这个数的c^2(较小平方项),根据这个相减就可以求出他们中间的ai了~
代码如下:
#include <bits/stdc++.h> #define mx 2e5 using namespace std; typedef long long ll; const int N =2e5+5; ll a[N]; int n; vector <int> Div[N]; int main(){ cin>>n; for(int i=2;i<=n;i+=2) scanf("%I64d",&a[i]); for(int i=1;i<=mx;i++) for(int j=i;j<=mx;j+=i) Div[j].push_back(i); //nlogn预处理 ll last = 0; for(int i=2;i<=n;i+=2){ ll mn=2e18; for(auto v:Div[a[i]]){ int d=a[i]/v; if(d%2==v%2){ ll now = (max(d,v)-min(d,v))/2; if(now*now>last) mn = min(mn,now*now); } } if(mn==2e18){ puts("No");return 0; } a[i-1]=mn-last; last = a[i]+mn; } puts("Yes"); for(int i=1;i<=n;i++){ printf("%I64d ",a[i]); } return 0; }
重要的是自信,一旦有了自信,人就会赢得一切。