列表

详情


NC200625. 陪你去流浪,踏遍那四海八荒

描述

巫山老伯一直想去远方流浪,踏遍四海八荒,攀登五岳珠峰!问世间情为何物,只教天若有情天亦老,人间正道是沧桑!
今日,巫山老伯再启程,去那北海极地,寻同道中人,看绝世美景。叹息,憾息。
巫山老伯,有一神秘法宝,助他踏遍四海,早寻同道中人,安看万世流景。此神秘法宝,极大的减轻了旅途中的负担。此神秘法宝,体积极小,外形堪似那古埃及的奇迹之做——金字塔。第一层可放容量为1的物件,第2层,可放容量不超过2的阶层的物件,第3层,可放容量不超过3的阶层的物件,第n层,可放容量不超过n的阶层的物件。以此类推 于是而已。
还有二件神秘宝物,可助他收藏旅途所收获之点点滴滴。
一为,万生药水;二为,万物归一。
万生药水,可以成倍复制那外形看似那金字塔的神秘法宝(例如:有n个神秘法宝,则可复制出2*n个神秘法宝)。
万物归一,可把多个神秘法宝归为一个神秘法宝,且体积会相应扩大,除第一层外其他所有层的容量都会变成相应层容量的和。
解释:如果有3个3层的神秘法宝,那么用了一个万物归一之后,变成的新的神秘法宝的容积将为(1+2!+2!+2!+3!+3!+3!)。
同时,万生药水和万物归一,巫山老伯是可以随便用的,但是要保证在最后一定要合成一个神秘法宝,同时要使容积是最大的(求模之前最大),不能同时带着多个神秘法宝行走于江湖。
例如:
巫山老伯此次出行带有,一个有3层的神秘法宝,2瓶万生药水,2瓶万物归一。那么此次出行巫山老伯最多能装(1+2! + 2! + 2! + 2! + 3! + 3! + 3! +3!)的容量物品。
解释:3层神秘法宝 可装容量为(1+2!+3!),用一瓶万生药水可装容量变成(1+2!+3!)+(1+2!+3!),在用一瓶万物归一则可装容量变为
(1+2!+2!+3!+3!);在用一瓶万生药水,可装容量变为(1+2!+2!+3!+3!)+(1+2!+2!+3!+3!),在用一瓶万物归一药水,可装容量变为
(1+2!+2! + 2!+2!+3!+3!+3!+3!)。
同时,巫山老伯为了保证神秘法宝过大,他会将每一层的容积对mod=3777105087进行取余(只要当前容积一大于mod,就进行取余)。然后重新得到每一层的容积。

输入描述

多组输入
第一行输入n 表示初始神秘法宝是多少层的 (1<= n<=1e15)
第二行 输入 x 和 y 分别表示x瓶万生药水,y瓶万物归一 (0<= x ,y <= 10)

输出描述

每行输出通过万生药水和万物归一的变换之后,最后的神秘法宝的容积。同时容积对mod取余。

示例1

输入:

2
1 1
3
2 1

输出:

5
33

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Java(javac 1.8) 解法, 执行用时: 69ms, 内存消耗: 11692K, 提交时间: 2020-04-11 15:07:07

import java.util.Scanner;

public class Main
{

	public static void main(String[] args) 
	{
		Scanner in=new Scanner(System.in);
		long mod=3777105087l;
		long n[]=new long[200];
		long m[]=new long[200];
		n[1]=1;
		for(int i=2;i<200;i++)
		{
			n[i]=n[i-1]*i%mod;
			m[i]=(n[i]+m[i-1])%mod;
		}
		while(in.hasNext())
		{
			long a=in.nextLong();
			int x=in.nextInt();
			int y=in.nextInt();
			long ans=1;
			if(y>0)
			{
				for(int i=1;i<=x;i++)
				{
					ans=ans*2;
				}
			}
			if(a>178)
			{
				System.out.println(m[178]*ans%mod+1);
			}
			else
			{
				System.out.println(m[(int)a]*ans%mod+1);
			}
		}
	}

}

C++14(g++5.4) 解法, 执行用时: 5ms, 内存消耗: 492K, 提交时间: 2020-04-11 17:01:27

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod=3777105087;
ll f[180],s[180];
int main()
{
    f[1]=1;
    for(int i=2;i<=178;i++){
        f[i]=f[i-1]*i%mod;
        s[i]=(s[i-1]+f[i])%mod;
    }
    ll n;
    while(cin>>n)
    {
        int x,y;
        ll a=1;
        cin>>x>>y;
        if(y) a=1<<x;
        if(n>178) cout<<s[178]*a%mod+1<<endl;
        else cout<<s[n]*a%mod+1<<endl;
    }
    system("pause");
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 3ms, 内存消耗: 504K, 提交时间: 2020-07-15 14:10:21

#include<bits/stdc++.h>
using namespace std;

const long long mod=3777105087;
long long i,ans,n,x,y,A[180],S[180]={0};
int main()
{
	S[2]=A[2]=2;
	for(i=3;i<=177;i++)A[i]=A[i-1]*i%mod,S[i]=(S[i-1]+A[i])%mod;
    while(~scanf("%lld%lld%lld",&n,&x,&y))
    {
    	if(n>177)n=177;
    	i=(1<<x),ans=(S[n]+1)%mod;
    	if(y)ans=(S[n]*i+1)%mod;
    	printf("%lld\n",ans);
	}
    return 0;
}

上一题