【刷题】洛谷 P2675 《瞿葩的数字游戏》T3-三角圣地

题目背景

国王1带大家到了数字王国的中心:三角圣地。

题目描述

不是说三角形是最稳定的图形嘛,数字王国的中心便是由一个倒三角构成。这个倒三角的顶端有一排数字,分别是1 ~ N。1 ~ N可以交换位置。之后的每一行的数字都是上一行相邻两个数字相加得到的。这样下来,最底端就是一个比较大的数字啦!数字王国称这个数字为“基”。国王1希望“基”越大越好,可是每次都自己去做加法太繁琐了,他希望你能帮他通过编程计算出这个数的最大值。但是这个值可能很大,所以请你输出它mod 10007 的结果。

任务:给定N,求三角形1~N的基的最大值 再去 mod 10007。

输入输出格式

输入格式:

一个整数N

输出格式:

一个整数,表示1~N构成的三角形的最大的“基”

输入输出样例

输入样例#1:

4

输出样例#1:

24

输入样例#2:

1125

输出样例#2:

700

说明

数据:

20% 0<=N<=100

50% 0<=N<=3000

100% 0<=N<=1000000

样例解释:

1 3 4 2

4 7 6

11 13

24 是N=4的时候的最大值,当然还有别的构成形式。

PS:它叫做三角圣地,其实它就是个三角形~

本题数据已经更新,目前全部正确无误!

不要面向数据编程!

题解

把三角形画出来之后,发现,数列里一个数在“基”被加的次数就是从它的位置走向底端的方案数
然后,\(ans=C_{n-1}^0a_0+C_{n-1}^1a_1+C_{n-1}^2a_2+...+C_{n-1}^{n-1}a_{n-1}=\sum_{i=0}^{n-1}C_{n-1}^ia_i\)
所以越往中间走,被加的次数就越多,那么贪心地把数列拍好,然后 \(O(n)\) 用Lucas算就好了

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=1000000+10,Mod=1e4+7;
int n,A[MAXN];
ll res,fac[MAXN],inv[MAXN];
template<typename T> inline void read(T &x)
{
	T data=0,w=1;
	char ch=0;
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')w=-1,ch=getchar();
	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
	x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
	if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline ll qexp(ll a,ll b)
{
	ll res=1;
	while(b)
	{
		if(b&1)res=res*a%Mod;
		a=a*a%Mod;
		b>>=1;
	}
	return res;
}
inline void init()
{
	fac[0]=1;
	for(register int i=1;i<Mod;++i)fac[i]=fac[i-1]*i%Mod;
	inv[Mod-1]=qexp(fac[Mod-1],Mod-2);
	for(register int i=Mod-2;i>=0;--i)inv[i]=inv[i+1]*(i+1)%Mod;
}
inline ll C(ll n,ll m)
{
	if(n<m)return 0;
	if(n<Mod&&m<Mod)return fac[n]*inv[m]%Mod*inv[n-m]%Mod;
	else return C(n/Mod,m/Mod)*C(n%Mod,m%Mod)%Mod;
}
int main()
{
	read(n);
	init();
	if(n&1)
	{
		A[(n>>1)+1]=n;A[(n>>1)+2]=n-1;
		for(register int i=(n>>1);i>=1;--i)A[i]=A[i+1]-2;
		for(register int i=(n>>1)+3;i<=n;++i)A[i]=A[i-1]-2;
	}
	else
	{
		A[1]=1;
		for(register int i=2;i<=(n>>1);++i)A[i]=A[i-1]+2;
		A[(n>>1)+1]=n;
		for(register int i=(n>>1)+2;i<=n;++i)A[i]=A[i-1]-2;
	}
	for(register int i=1;i<=n;++i)(res+=C(n-1,i-1)*A[i]%Mod)%=Mod;
	write(res,'\n');
	return 0;
}
posted @ 2018-04-30 17:32  HYJ_cnyali  阅读(157)  评论(0编辑  收藏  举报