zoukankan      html  css  js  c++  java
  • hdu 5976 Detachment 脑洞题 猜结论

    题目链接

    题意

    (x)拆成(a_1+a_2+...+)的形式,且(a_1lt a_2lt...),使得(a_1*a_2*...)取到最大值

    思路

    大胆猜结论。

    首先拆分的形式中肯定不能有(1).

    于是预处理出前缀和(a[i]=sum_{k=2}^{i}k)

    找到(geq x)的最小的(a[id]),接下来:

    1. 如果(a[id]==x),意味着(2+3+...+id=x),那么答案就是(2*3*...*id=factorial(id))
    2. 否则,求和时就省去超过部分对应的项(a[id]-x),即$$2+3+...+(a[id]-x-1)+(a[id]+x+1)+...+id=x$$答案就是(factorial(id)/(a[id]-x))

    且慢!如果超过的部分是(1),本来就不在求和项中怎么办啊?

    (继续猜)那么就将(2)省去,再给最后一项加上(1),即(3+4+...+(id-1)+(id+1)=x),答案就是(factorial(id-1)/2*(id+1)).

    就此,三种情况完毕,猜完,(A)了。

    Code

    #include <bits/stdc++.h>
    #define maxn 50000
    using namespace std;
    typedef long long LL;
    const LL mod = 1e9+7;
    LL a[maxn+10], fac[maxn+10];
    LL poww(LL a, LL b) {
        LL ret = 1;
        while (b) {
            if (b & 1) (ret *= a) %= mod;
            (a *= a) %= mod;
            b >>= 1;
        }
        return ret;
    }
    void init() {
        a[0] = a[1] = 0, a[2] = 2;
        for (int i = 3; i <= maxn; ++i) a[i] = a[i-1] + i;
        fac[1] = 1;
        for (int i = 2; i <= maxn; ++i) fac[i] = fac[i-1] * i % mod;
    }
    void work() {
        int n;
        scanf("%d", &n);
        if (n == 1) { printf("1
    "); return; }
        int id = lower_bound(a, a+maxn, n) - a;
        LL ans;
        if (a[id] == n) ans = fac[id];
        else if (a[id]-n > 1) ans = fac[id] * poww(a[id]-n, mod-2) % mod;
        else ans = fac[id-1] * poww(2, mod-2) % mod * (id+1) % mod;
        printf("%lld
    ", ans);
    }
    int main() {
        init();
        int T;
        scanf("%d", &T);
        while (T--) work();
        return 0;
    }
    
    
  • 相关阅读:
    分析函数
    HIBERNATE锁机制
    面试小计
    java Base64算法的使用
    Mac & XCode 使用技巧总结
    设计模式-15 模板模式
    Struts学习总结-02 上传文件
    java学习总结
    Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO的概念
    设计模式-14 MVC模式
  • 原文地址:https://www.cnblogs.com/kkkkahlua/p/7669171.html
Copyright © 2011-2022 走看看