乘积最大,求逆元

http://oj.jxust.edu.cn/contest/Problem?id=1702&pid=4

题意:给你一个数n,分成几个数之和使这些数乘积最大x。

求(1/n) %x.

解法:要使乘积最大尽可能多的分出3 , 三种情况,

1、n%3 == 0 ,全分成3的乘积。

2、n%3 == 1 , 分成n/3-1个3,和一个4.

3、n%3 == 2 , 分成n/3个3,和一个2.

 

另外注意费马小定理求逆元时,x要为素数。

所以该题最好使用拓展欧几里得求逆元。

//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
#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 20191117
#define PI acos(-1)
using namespace std;
typedef long long ll ;
ll x , y , d ;

void gcd(ll a , ll b , ll &d , ll &x , ll &y)
{
    if(!b)
    {
        x = 1 ;
        y = 0 ;
        d = a ;
    }
    else
    {
        gcd(b , a%b , d , x , y);
        ll t = x ;
        x = y ;
        y = t - (a / b) * y;
    }
}

ll cal(ll a , ll b)
{
    gcd(a , b , d , x , y);
    if(d == 1)
    {
        return (x % b + b) % b ;
    }
    else
    {
        return -1 ;
    }
}

int main()
{

    ll n ;
    scanf("%lld" , &n);
    ll x ;
    if(n % 3 == 0)
    {
        x = pow(3 , n / 3);
    }
    else if(n % 3 == 1)
    {
        x = pow(3 , n / 3 - 1) * 4 ;
    }
    else if(n % 3 == 2)
    {
        x = pow(3 , n / 3) * 2 ;
    }
    printf("%lld\n" , cal(n , x));

    return 0;
}

 

posted @ 2019-11-24 22:52  无名菜鸟1  阅读(147)  评论(0编辑  收藏  举报