• 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;
    }
    
  • 相关阅读:
    算法与数据结构9
    算法与数据结构8
    数据结构与算法7
    数据结构与算法6
    计算机视觉(七)
    计算机视觉(六)
    计算机视觉(五)
    vscode 创建java项目
    vue 访问API接口
    vscode+vue 框架搭建
  • 原文地址:https://www.cnblogs.com/-pwl/p/14082552.html
Copyright © 2020-2023  润新知