【刷题】洛谷 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;
}

原文地址:https://www.cnblogs.com/hongyj/p/8974113.html

时间: 2024-10-19 15:01:47

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

P2675 《瞿葩的数字游戏》T3-三角圣地

传送门 考虑最上面每个位置的数对答案的贡献 然后就很容易发现: 如果有n层,位置 i 的数对答案的贡献就是C( n-1,i ) 然后就有很显然的贪心做法: 越大的数放越中间,这样它的贡献就会尽可能的大 然后考虑算C( i,j ) 因为n很大,模数很小 所以要用lucas定理求C C(n,m)= C(n/mo,m/mo)*C(n%mo,m%mo) 当C比较小的时候可以直接用阶乘和阶乘逆元算出 #include<iostream> #include<cstdio> #include&l

《瞿葩的数字游戏》T3-三角圣地(Lucas)

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

洛谷P1538迎春舞会之数字舞蹈

题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈”.顾名思义就是所有人一起排成若干个数字 -___-|||| 更为创新的是,每个人都是趴在地上,保证横竖. 现在给出数字及其要求摆出的大小,请你编程,模拟同学们的优美姿态. 输入输出格式 输入格式: 第一行为k.k表示要摆出数字的大小. 第二行为全部由数字组成的字符串,即要摆出的几个数字. 输出格式

kmp字符串匹配基础模板题 (洛谷P3375 )

如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了. 输入样例#1: ABABABC ABA 输出样例#1: 1 3 0 0 1 因为要求next的值,所以这里不加优化了把代码进行稍微的改动标记即可 #include<bits/stdc++.h> using namespace std; int next[2000000]; c

网络流24题 第一题 - 洛谷2756 飞行员配对方案 二分图匹配 匈牙利算法

欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 题意概括 裸的二分图匹配 题解 匈牙利算法 上板子 代码 #include <cstring> #include <cstdio> #include <algorithm> #include <cstdlib> #include <cmath> using namespace std; const int N=100+5; int m,n,a,b,match[N

水题-洛谷P1209-最大公约数与最小公倍数问题

一个萌新的成长之路 Discription 输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数 条件: 1.P,Q是正整数 2.要求P,Q以x0为最大公约数,以y0为最小公倍数. 试求:满足条件的所有可能的两个正整数的个数. Input&Output 输入格式: 二个正整数x0,y0 输出格式: 一个数,表示求出满足条件的P,Q的个数 Example Input: 3 60 Output: 4 Solution

网络流24题 洛谷 3355 骑士共存

转换成最小割: #include <bits/stdc++.h> using namespace std ; const int mx [ 9 ] = { 2 , 2 , -2 , -2 , -1 , 1 , -1 , 1 } ; const int my [ 9 ] = { -1 , 1 , -1 , 1 , 2 , 2 , -2 , -2 } ; const int N = 100000 + 10 , inf = 1e8 + 7 ; queue < int > q ; int

网络流24题 洛谷 4014 分配问题

代码风格迥异 -- #include<bits/stdc++.h> const int N=100+10,M=100000+10; using namespace std; queue<int> q; int head[M],dis[M],flt[M],to[M],nxt[M],cn=1; int c[N],pree[N],pred[N],a[N][N]; int maxcost,mincost,src,sink,tmp,n,x; bool vis[N]; void create(

网络流24题 洛谷 2756 飞行员配对方案

代码风格迥异 -- 1 #include<bits/stdc++.h> 2 3 const int N=1000+5; 4 5 using namespace std; 6 7 int link[N],g[N][N],ansx[N]; 8 int n,m,u,v,ans; 9 bool vis[N]; 10 11 inline void read( int&x ) { 12 int f=1;x=0;char c=getchar(); 13 while(c>'9'||c<'0