zoukankan      html  css  js  c++  java
  • 数论(费马小定理求逆元+前缀和)

    http://acm.hdu.edu.cn/showproblem.php?pid=5976

    题意:给你一个数n,拆成不同的几份,使乘积最大。

    解法:从2开始拆 2 , 3 , 4 ....l  , 最后会余下x , 0<=x <= l ;

    再将x从后往前依次分配1给各元素。

    1、x == l:3*4*5*...l * (l+2)  = (csum[l] / 2) % mod * (l+2) (除以2要转为乘以2的逆元)

    2、x == 0 : 2*3*...*l = csum[l]

    3、x != 0 && x != l : 2 * 3 *...k * k+2*...l+1 = csum[l+1] / (index - c+ 1) (逆元求解)

    //#include <bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <stdio.h>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <string.h>
    #include <vector>
    #define ME(x , y) memset(x , y , sizeof(x))
    #define SF(n) scanf("%d" , &n)
    #define rep(i , n) for(int i = 0 ; i < n ; i ++)
    #define INF  0x3f3f3f3f
    #define mod 1000000007
    using namespace std;
    typedef long long ll ;
    ll sum[100009];
    ll csum[100009];
    
    
    ll quickpow(ll a , ll b)
    {
        ll ans = 1 ;
        while(b)
        {
            if(b&1)
            {
                ans = ans * a % mod ;
            }
            b >>= 1 ;
            a = a * a % mod;
        }
        return ans ;
    }
    
    int main()
    {
        ll t ;
        scanf("%lld" , &t);
        for(int i = 2 ; i <= 100000 ; i++)
        {
            sum[i] += sum[i-1] + i ;
        }
        csum[1] = 1 ;
        for(int i = 2 ; i <= 100000 ; i++)
        {
            csum[i] = (csum[i-1] * i) % mod ;
        }
    
        while(t--)
        {
            ll n ;
            scanf("%lld" , &n);
            if(n <= 4)
            {
                printf("%lld
    " , n);
                continue ;
            }
            int index = upper_bound(sum , sum+100000 , n) - sum;
            index-- ;
            if(n - sum[index] == 0)
            {
                printf("%lld
    " , csum[index]);
            }
            else if(n - sum[index] == index)
            {
                printf("%lld
    " , csum[index] % mod * quickpow(2 , mod-2) % mod * (index + 2) % mod);
            }
            else
            {
                ll c = n - sum[index];
                printf("%lld
    " , csum[index] % mod * quickpow(index - c + 1 , mod - 2) % mod * (index+1) % mod);
            }
    
    
    
        }
    
    
        return 0 ;
    }
  • 相关阅读:
    使用Webuploader大文件分片传输
    php面向对象的封装性
    前端实习经历
    Js_protoType_原型
    SVN客户端与服务器端搭建操作
    安装PL/SQL客户端来访问操作步骤
    安装Oracle数据库操作步骤
    MyEclipse2014安装操作步骤+破解
    模块学习笔记
    json与导入模块目录
  • 原文地址:https://www.cnblogs.com/nonames/p/11870283.html
Copyright © 2011-2022 走看看