zoukankan      html  css  js  c++  java
  • Lcez#111 yist

    原题题面

    Description

    给定 (n),求 (n! \% 2^{32})

    Solution

    60pts

    暴力。

    Code
    #include<iostream>
    #include<cstdio>
    #define ll long long
    using namespace std;
    const ll Mod=4294967296;
    inline ll f(ll x){
    	ll res=1;
    	for(ll i=1;i<=x;i++) res=res*i%Mod;
    	return res%Mod;
    }
    int main(){
    	//freopen("out.txt","w",stdout);
    	int t;
    	ll n;
    	scanf("%d",&t);
    	for(int i=1;i<=t;i++){
    		scanf("%lld",&n);
    		printf("%lld
    ",f(n)%Mod);
    	}
    	return 0;
    }
    

    100pts

    显然,不能得到 100pts 的原因是 (f) 函数耗时太久。

    考虑如何优化。

    优化不难想到针对模数((2^{32}))进行优化。

    如果无法一眼看出结论的话,用 60pts 的代码先打一个表尝试推一推结论 / 规律。

    可以打出这样的表

    不难发现,在 2147483648 后,即 (2^{31}) 之后,结果全部为 0 。

    道理也不难理解,在 (n) 足够大后,一定有一个 (n) ,使得 (2^{32} | n!)

    之后的所有数再继续往下乘,结果依然为 (0)

    所以在 (f) 函数中加一句特判,即可大大降低时间复杂度。

    inline ll f(ll x){
    	ll res=1;
    	for(ll i=1;i<=x;i++){
    		if(res*i%Mod==0) return 0;
    		res=res*i%Mod;
    	}
    	return res%Mod;
    }
    

    Code

    #include<iostream>
    #include<cstdio>
    #define ll long long
    using namespace std;
    const ll Mod=4294967296;
    inline ll f(ll x){
    	ll res=1;
    	for(ll i=1;i<=x;i++){
    		if(res*i%Mod==0) return 0;
    		res=res*i%Mod;
    	}
    	return res%Mod;
    }
    int main(){
    	//freopen("in.txt","r",stdin);
    	//freopen("out.txt","w",stdout);
    	int t;
    	ll n;
    	scanf("%d",&t);
    	for(int i=1;i<=t;i++){
    		scanf("%lld",&n);
    		printf("%lld
    ",f(n)%Mod);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Beta 第七天
    Beta 第六天
    Beta 第五天
    Beta 第四天
    Beta 第三天
    Beta 第二天
    Beta 凡事预则立
    Beta 第一天
    Beta 集合
    打造专属测试平台5-使用Docker部署MySQL数据库
  • 原文地址:https://www.cnblogs.com/-pwl/p/14082552.html
Copyright © 2011-2022 走看看