zoukankan      html  css  js  c++  java
  • ACM-ICPC 2018 焦作赛区网络预赛 G. Give Candies (打表找规律+快速幂)

    题目链接:https://nanti.jisuanke.com/t/31716

     

    题目大意:有n个孩子和n个糖果,现在让n个孩子排成一列,一个一个发糖果,每个孩子随机挑选x个糖果给他,x>=1,直到无糖果剩余为止。给出数字n,问有多少种分发糖果的方法。

    样例输入

    1
    4

    样例输出

    8

     

    解题思路:我们可以这样想,一个糖果的话,应该是只有1种方法记为x1,如果是两个糖果的话,有两种方法即为x2,分别为(1,1)和(2),从中我们可以想到如果n个糖果的话,就可以分为第n个人取1个的话就有x(n-1)种,去两个的话就有x(n-2)种,依次类推,第n个人取n-1个的话就有x1种方法,第n个人取n个的话就只有1种方法。即x(n)=x1+x2+……+x(n-1)+1=2^(n-1);

    其实就是一个简单的拆数问题,比如这里有三个学生,老师有三个糖果,有四种分法:{3,0,0},
    {2,1,0},{1,2,0},{1,1,1}

    一个数的拆法其实就是2^(N-1)

     

    也可以打表找规律,都很简单。

    但是有一个难点是n的范围特别大,可以达到10^100000,不能通过整型数字存储,而只能用字符数组存储这个数,这样的话我们肯定不能直接用快速幂。所以这里就要采用一个小技巧,也就是一个性质,2^N模一个质数,它的结果是具有周期性的,周期长度为mod-1,这道题就利用这个周期
    性质,具体步骤就是:先把n转化成模mod-1下的的数,然后用这个数计算快速幂。

     

    附上代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const ll mod=1e9+7;
    char s[100005];
    
    ll qpow(ll a,ll n)
    {
        ll ans=1;
        while(n)
        {
            if(n&1) ans=(ans*a)%mod;
            n>>=1;
            a=(a*a)%mod;
        }
        return ans;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%s",s);
            int len=strlen(s);
            ll MOD=mod-1,temp=0;
            for(int i=0;i<len;i++)
                temp=(temp*10+s[i]-'0')%MOD;  //将n转化成mod-1内的数
            if(temp==0) temp=MOD; //特判temp==0时,temp即为mod-1
            temp=(temp-1+MOD)%MOD;
            ll ans=qpow(2,temp);
            cout<<ans<<endl;
        }
        return 0;
    }

     

  • 相关阅读:
    [转]Spring Cloud在国内中小型公司能用起来吗?
    [转]关于maven pom.xml中dependency type 为pom的应用
    如何直接在github网站上更新你fork的repo?
    Eclipse在Tomcat环境下运行项目出现NoClassDefFoundError/ClassNotFoundException解决办法
    Jquery mobile 中在列表项上使用单选按钮
    QBus 关注并推送实时公交信息
    常用序列号
    SVN 使用锁实现独占式签出
    SQL速记
    利用交通在手数据为换乘添加关注
  • 原文地址:https://www.cnblogs.com/zjl192628928/p/9678184.html
Copyright © 2011-2022 走看看