常州大学新生赛 G-零下e度

链接:https://www.nowcoder.net/acm/contest/78/G
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

在家好冷!
又多冷呢?
大概是零下e度!
为什么是零下e度呢?
不知道,因为我编不下去了。
求给定一个数n,求出最接近n!/e的整数


输入描述:

一行一个整数n
1<=n<=10^8

输出描述:

一行一个整数,即题目描述中所求,由于这个数字可能很大,我们只需要知道mod 998244353后的结果(出题人负责任地告诉你,这个数字是个质数)
示例1

输入

6

输出

265
示例2

输入

87

输出

158005593
示例3

输入

16777216

输出

16065816

结论:最接近n!/e的整数即为错排公式的第n项。
1e8的带模递推即可,734ms,取模时优化一下能570ms左右
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <iomanip>
#include <cctype>
#include <cassert>
#include <bitset>
#include <ctime>

using namespace std;

#define pau system("pause")
#define ll long long
#define pii pair<int, int>
#define pb push_back
#define mp make_pair
#define clr(a, x) memset(a, x, sizeof(a))

const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
const double EPS = 1e-9;

int n;
ll ans;
int main() {
    scanf("%d", &n);
    int x = (n - 1) / 10000;
    int y = (n - 1) % 10000;
    ll res1 = 0, res2 = 1;
    if (1 == n) {
        printf("%lld\n", res1);
    } else if (2 == n) {
        printf("%lld\n", res2);
    } else {
        for (int i = 3; i <= n; ++i) {
            ans = (i - 1) * (res1 + res2);
            if (ans > MOD) {
                ans %= MOD;
            }
            res1 = res2;
            res2 = ans;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

 

posted @ 2018-02-07 20:15  hit_yjl  阅读(227)  评论(0编辑  收藏  举报