Codeforces Round #419 D. Karen and Test
Karen has just arrived at school, and she has a math test today!
The test is about basic addition and subtraction. Unfortunately, the teachers were too busy writing tasks for Codeforces rounds, and had no time to make an actual test. So, they just put one question in the test that is worth all the points.
There are n integers written on a row. Karen must alternately add and subtract each pair of adjacent integers, and write down the sums or differences on the next row. She must repeat this process on the values on the next row, and so on, until only one integer remains. The first operation should be addition.
Note that, if she ended the previous row by adding the integers, she should start the next row by subtracting, and vice versa.
The teachers will simply look at the last integer, and then if it is correct, Karen gets a perfect score, otherwise, she gets a zero for the test.
Karen has studied well for this test, but she is scared that she might make a mistake somewhere and it will cause her final answer to be wrong. If the process is followed, what number can she expect to be written on the last row?
Since this number can be quite large, output only the non-negative remainder after dividing it by \(10^9+7\).
题目大意:
给定N个数,每一次交错填写+-号,然后将结果放到下一行,然后继续交错填写,求最后一行的答案
解题报告:
好久以前的坑.....
手玩N=6和样例发现:
最后的结果可以表示为\(x1*a1+x2*a2+..+xn*an\),\(x\)是\(ai\)的系数,然后发现如果N为偶数就可以分偶数项和奇数项讨论,两者计算的方式是一样的.
再进一步又发现单独看奇偶项满足二项式定理,所以直接用组合数计算系数即可,但是对于N为4的倍数的情况答案是奇数项-偶数项,讨论一下即可
对于N不为偶数的情况我们可以先算出下一行然后做同样的步骤即可
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=200005,mod=1e9+7;
int a[N],n;ll w[N],mul[N],ni[N];
ll qm(ll x,ll k){
ll sum=1;
while(k){
if(k&1)sum*=x,sum%=mod;
x*=x;x%=mod;k>>=1;
}
return sum;
}
ll C(int n,int k){return mul[n]*ni[k]%mod*ni[n-k]%mod;}
void work()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
if(n<=2){printf("%d\n",(a[1]+a[2])%mod);return ;}
if(n%2){
n--;
for(int i=1;i<=n;i++)
w[i]=(i%2?a[i]+a[i+1]:a[i]-a[i+1]),
w[i]=(w[i]%mod+mod)%mod;
}
else for(int i=1;i<=n;i++)w[i]=a[i];
mul[0]=1;ni[0]=1;
for(int i=1;i<=n;i++)
mul[i]=mul[i-1]*i%mod,ni[i]=qm(mul[i],mod-2);
ll ans=0;
int hx=(n%4?1:-1);
for(int i=1;i<=n;i+=2){
ans+=C((n>>1)-1,i>>1)*(w[i]+hx*w[i+1]%mod)%mod;
if(ans>=mod)ans-=mod;
}
ans=((ans%mod)+mod)%mod;
printf("%lld\n",ans);
}
int main()
{
work();
return 0;
}