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

题目背景

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

题目描述

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

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

输入输出格式

输入格式:

一个整数N

输出格式

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

思路:

其实这道题大家画个图就会发现,1~n个数在他们自己位置上的权值是杨辉三角形第n行

由于可以交换位置,所以将最大的放在中间即可

于是开始算了

一开始,我用的递推组合数直接求一行杨辉三角形

50分??

哦,1000000太大了,递推会出锅

好吧,Lucas来一发

还是50分??

好吧,TLE出锅了

怎么办呢?
看来只能预处理阶乘了。。。

心累。。

递推版:

#include<iostream>
#include<cstdio>
using namespace std;
long long n,m,p,t,ans[1000010],ny[1000010],out;
void qny()
{
    ny[1]=1;
    for(register int a=2;a<=n;a++)
    {
        ny[a]=(p-(p/a))*ny[p%a]%p;
    }
}
int main()
{
    scanf("%d",&n);
    p=10007;
    qny();
    m=(n+1)/2;
    ans[0]=1;
    for(register int i=1;i<=m-1;i++)
    {
        ans[i]=ans[i-1]*(n-i)*ny[i]%p;
    }
    for(register int i=2;i<=n;i+=2)
    {
        long long ltt=i+i-1;
        ltt%=p;
        ltt*=ans[i/2-1];
        ltt%=p;
        out+=ltt;
        out%=p;
    }
    if(n%2==1)
    {
        long long ltt=n*ans[m-1]%p;
        out+=ltt;
        out%=p;
    }
    cout<<out;
}

Lucas朴素版:

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#define rii register int i
using namespace std;
unsigned long long n,m,p,t,ny[100010],out;
void qny()
{
    ny[1]=1;
    for(register int a=2;a<=p;a++)
    {
        ny[a]=(p-(p/a))*ny[p%a]%p;
    }
}
int zhs(int q,int x)
{
    if(q==0)
    {
        return 1;
    }
    long long ltt=1;
    for(register int a=1;a<=q;a++)
    {
        ltt*=ny[a];
        ltt%=p;
    }
    for(register int a=1;a<=q;a++)
    {
        ltt*=(x-a+1);
        ltt%=p;
    }
    return ltt;
}
long long lucas(int s,int t)
{
    if(t==0)
    {
        return 1;
    }
    else
    {
        return (lucas(s/p,t/p)*zhs(s%p,t%p))%p;
    }
}
int main()
{
    scanf("%d",&n);
    p=10007;
    qny();
    for(rii=1;i<=n;i+=2)
    {
        if(i==n)
        {
            out+=lucas(i/2,n-1)*(i);
        }
        else
        {
            out+=lucas(i/2,n-1)*(i*2+1);
        }
        out%=p;
    }
    cout<<out;
}

正解:

#include<iostream>
#include<cstring>
#define rii register int i
using namespace std;
int p=10007;
long long jc[10010],ny[10010],n,ans;
void ycl()
{
    jc[0]=1;
    jc[1]=1;
    ny[0]=1;
    ny[1]=1;
    for(rii=2;i<=p-1;i++)
    {
        jc[i]=jc[i-1]*i%p;
    }
    for(rii=2;i<=p-1;i++)
    {
        ny[i]=(p-p/i)*ny[p%i]%p;
    }
    for(rii=1;i<=p-1;i++)
    {
        ny[i]=ny[i-1]*ny[i]%p;
    }
}
long long lucas(long long h,long long j)
{
    if(h<j)
    {
        return 0;
    }
    if(h<p&&j<p)
    {
        return jc[h]*ny[j]%p*ny[h-j]%p;
    }
    return lucas(h/p,j/p)*lucas(h%p,j%p)%p;
}
int main()
{
    ycl();
    cin>>n;
    for(rii=1;i<=n;i++)
    {
        if(i%2==0)
        {
            ans=(ans+(i*lucas(n-1,n-i/2))%p)%p;
            if(ans<0)
            {
                ans+=p;
            }
        }
        else
        {
            ans=(ans+(lucas(n-1,(i+1)/2-1)*i)%p)%p;
            if(ans<0)
            {
                ans+=p;
            }
        }
    }
    cout<<ans;
}

  

原文地址:https://www.cnblogs.com/ztz11/p/9209182.html

时间: 2024-10-27 04:52:12

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

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

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

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

猜数字 游戏

前几天一直做的一个小游戏,猜数字游戏,开始不会做,通过老师的帮助还是成功做出来了,也算小有成就了,嘿嘿. 下面给大家看看我做的这个小游戏: public class GuessNumber { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("\t****** 猜数字 ******\n"); System.out.println("

Vijos P1218 数字游戏

描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分为m个部分,各部分内的数字相加,相加所得的m个结果对10取模后再相乘,最终得到一个数k.游戏的要求是使你所得的k最大或者最小. 格式 输入格式 输入文件第一行有两个整数,n(1≤n≤50)和m(1≤m≤9).以下n行每行有个整数,其绝对值不大于10^410?4??,按顺序给出圈中的数字,首尾相接. 输出

JavaScript一个猜数字游戏

效果图: 代码: <body> <script type="text/javascript"> window.onload = newgame; //页面载入的时候就开始一个新的游戏 window.onpopstate = popState; //处理历史记录相关事件 var state,ui; //全局变量,在newgame()方法中会对其初始化 function newgame( playagin ){ //开始一个新的猜数字游戏 //初始化一个包含需要的文

BZOJ2900 好玩的数字游戏

好玩的数字游戏 TK在虐题的同时,也喜欢玩游戏.现在,有这样的一个游戏,规则是这样的:先随机给出一个数字N,然后你在操场上把1到N的所有数字写成一排,就像这样:123456789101112131415-.接着你在每个数字前面添上加减号,每逢排在奇数位上的数字,就写上加号:每逢排在偶数位上的数字,就写上减号.恩-最后你得到一个超级长的式子.并且可以算出这个式子的结果.TK觉得这个游戏很有意思,于是他没日没夜地玩啊玩啊玩啊-或许你觉得这个游戏没有意思-恩-但是,如果你是TK,对于给定的N,你能够算

猜数字游戏及rand()函数

#include<stdio.h>#include<stdlib.h>int main() { short number; short guess=0; number=rand()%100; number++; printf("猜数字游戏\n"); printf("该数字在1到100之间\n"); while(guess!=number) { printf("请你输入所猜数字:"); scanf("%hd&quo

DP——数字游戏

Description 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分为m个部分,各部分内的数字相加,相加所得的m个结果对10取模后再相乘,最终得到一个数k.游戏的要求是使你所得的k最大或者最小. 例如,对于下面这圈数字(n=4,m=2): 当要求最小值时,((2-1) mod 10)×((4+3) mod 10)=1×7=7,要求最大值时,为((2+4

原创Android游戏--猜数字游戏V1.1 --数据存储,Intent,SimpleAdapter的学习与应用

--------------------------------------------------------------- V0.1版本 上次做完第一个版本后,发现还有一些漏洞,并且还有一些可以添加的功能,以及一些可改进的地方,于是准备继续完善此游戏,顺便学Android了. 本次更新信息如下: 1.改正了随机数生成算法,更正了不能产生数字'9'的bug 2.增加了数据存储与IO的内容,使用了SharedPreferences保存数据 3.保存数据为: 总盘数,猜中的盘数 4.使用了Simp