标签:而且 问题 string fine scanf int gravity const class
看到这题的复杂度就大概可以知道只是一道规律题了。
但问题是,规律是什么?
我们观察一下题目,不可能去模拟所有情况是吧,我们又发现所有想都是由上一层的数推过来的,于是我们可以把结果用最开始的给出项的系数直接算出来。
但问题又来了,n不同时,各项的系数怎么算呢?
于是我们开始找规律:
(下面的来自别人的博客)
n=4*k+1的时候,系数都是a1,0,a2,0,a3……a3,0,a2,0,a1的类型。
这是因为由一个固定的n=5的三角形(1,0,2,0,1)变化过来。
而且从加开始或从减开始都是一样的。
偶数位零是没用的,所以减法和加法也就是一样的(-0=+0)。
n=9时
| 1 | 0 | 4 | 0 | 6 | 0 | 4 | 0 | 1 |
|---|---|---|---|---|---|---|---|---|
| 1 | 0 | 2 | 0 | 1 | ||||
| 1 | 0 | 2 | 0 | 1 | ||||
| 1 | 0 | 2 | 0 | 1 | ||||
| 1 | 0 | 2 | 0 | 1 |
把n暴力变成4*k+1的形式。O(4N)
而且这个系数除去0,跟杨辉三角的第2*(k/2)+1行是一模一样的。
杨辉三角:
1
11
121
1331
14641
……
快速幂……O(4N+N log mod)
代码(不是我的代码,我写的注释):
#include<cstdio>
#include<cstring>
#include<algorithm>
#define imin(a,b) ((a<b)?(a):(b))
#define imax(a,b) ((a>b)?(a):(b))
using namespace std;
typedef long long ll;
const ll mods=1e9+7;
const int N=200100;
int n,col;
int d[N];
ll f[2][N],ans;//f模拟最开始最多4次运算,因为只和上一行有关系,所以只保存两行
ll Pow(ll x,ll y)
{
ll s=1ll;
for(;y;y>>=1)
{
if(y&1) s=(s*x)%mods;
x=(x*x)%mods;
}
return s;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&d[i]),f[1][i]=d[i];
col=0; int o=1;//o是当前行,col是下一行
while((n%4)!=1)//把n转换到4×k+1上去
{
o=o^1;
for(int i=1;i<n;i++)
{
col^=1;
if(col) f[o][i]=((f[o^1][i]+f[o^1][i+1])%mods+mods)%mods;
else f[o][i]=((f[o^1][i]-f[o^1][i+1])%mods+mods)%mods;
}
n--;
}
ll yi=(n-1)>>1;
ll C=1;
for(int i=0;i<=yi;i++)//枚举这一行不为零的系数
{
if(i) C=(C*(yi-i+1))%mods*Pow(i,mods-2)%mods;//系数
ans=(ans+C*f[o][i<<1|1]%mods)%mods;
}
printf("%lld\n",ans);
return 0;
}
标签:而且 问题 string fine scanf int gravity const class
原文地址:http://www.cnblogs.com/gshdyjz/p/7674393.html