Submission #4050654
Source Code Expand
#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <map>
using namespace std;
#define unittest_name_helper(counter) unittest_ ## counter
#define unittest_name(counter) unittest_name_helper(counter)
#define unittest __attribute__((constructor)) void unittest_name(__COUNTER__) ()
using QWORD = unsigned long long;
using SQWORD = long long;
using DWORD = unsigned int;
using SDWORD = int;
using WORD = unsigned short;
using SWORD = short;
using BYTE = unsigned char;
using SBYTE = char;
using DOUBLE = double;
using FLOAT = float;
#define MIN_SDWORD (-2147483648)
#define MAX_SDWORD (2147483647)
#define MIN_SBYTE (-128)
#define MAX_SBYTE (127)
#define MIN_SQWORD (0x8000000000000000)
#define MAX_SQWORD (0xFFFFFFFFFFFFFFFF)
#define MAX_QWORD (0xFFFFFFFFFFFFFFFF)
#define MAX_DWORD (0xFFFFFFFF)
#define MAX_WORD (0xFFFF)
#define MAX_BYTE (0xFF)
#define ArrayLength(a) (sizeof(a) / sizeof(a[0]))
static inline QWORD MAX(QWORD a, QWORD b) { return a > b ? a : b; }
static inline DWORD MAX(DWORD a, DWORD b) { return a > b ? a : b; }
static inline SDWORD MAX(SDWORD a, SDWORD b) { return a > b ? a : b; }
static inline QWORD MIN(QWORD a, QWORD b) { return a < b ? a : b; }
static inline DWORD MIN(DWORD a, DWORD b) { return a < b ? a : b; }
static inline SDWORD MIN(SDWORD a, SDWORD b) { return a < b ? a : b; }
#define BYTE_BITS (8)
#define WORD_BITS (16)
#define DWORD_BITS (32)
#define QWORD_BITS (64)
using M_BOOL = bool;
#define M_TRUE (true)
#define M_FALSE (false)
#define DIVISOR (1000000007)
static inline void inputString(char *pcStr)
{
char *pcCur = pcStr;
for (;;) {
char c = getchar();
if (('\n' == c) || (EOF == c)) {
break;
}
*pcCur = c;
pcCur++;
}
*pcCur = '\0';
}
static inline SDWORD inputSDWORD(void)
{
SDWORD lNumber = 0;
SDWORD lMultiplier = 1;
M_BOOL bRead = M_FALSE;
for (;;) {
char c = getchar();
if (!bRead) {
if ('-' == c) {
lMultiplier = -1;
}
}
if (('0' <= c) && (c <= '9')) {
lNumber *= 10;
lNumber += (c - '0');
bRead = M_TRUE;
} else {
if (bRead) {
return lNumber * lMultiplier;
}
}
}
}
static inline DOUBLE inputFP(void)
{
DOUBLE dInt = 0.0;
DOUBLE dFrac = 0.0;
DOUBLE dMultiplier = 1.0;
DWORD dwFpCnt = 0;
DOUBLE *pdCur = &dInt;
M_BOOL bRead = M_FALSE;
for (;;) {
char c = getchar();
if (!bRead) {
if ('-' == c) {
dMultiplier = -1;
}
}
if ('.' == c) {
pdCur = &dFrac;
} else if (('0' <= c) && (c <= '9')) {
(*pdCur) *= 10;
(*pdCur) += (DOUBLE)(c - '0');
bRead = M_TRUE;
if (pdCur == &dFrac) {
dwFpCnt++;
}
} else {
if (bRead) {
return dMultiplier * (dInt + dFrac / (pow((DOUBLE)10.0 , (DOUBLE)dwFpCnt)));
}
}
}
}
static DWORD powMod(DWORD x, DWORD k, DWORD m)
{
DWORD dwRes = 1;
while (k > 0) {
if (k & 1) {
dwRes = ((QWORD)dwRes * (QWORD)x) % (QWORD)m;
--k;
} else {
x = ((QWORD)x * (QWORD)x) % (QWORD)m;
k >>= 1;
}
}
return dwRes % m;
}
static DWORD modInv(DWORD g, DWORD p) {
return powMod(g, p - 2, p);
}
static DWORD normalSearch(DWORD dwInput_X, DWORD dwInput_P, DWORD dwInput_A, DWORD dwInput_B)
{
DWORD dwMin = powMod(dwInput_X, dwInput_A, dwInput_P);
for (DWORD dwPow = dwInput_A+1; dwPow <= dwInput_B; dwPow++) {
DWORD dwMod = powMod(dwInput_X, dwPow, dwInput_P);
dwMin = MIN(dwMin, dwMod);
}
return dwMin;
}
/**
* @brief baby step giant step algorithm
*/
uint32_t baby_step_giant_step(uint32_t g, uint32_t y, uint32_t p) {
uint32_t sqrt_p = sqrt(p);
unordered_map<uint32_t, int> baby;
uint32_t gb = 1;
for (int b = 0; b < sqrt_p + 3; b++) {
baby[gb] = b;
gb = (uint64_t)gb * g % p;
}
uint32_t g_sqrt_p_inv = modInv(powMod(g, sqrt_p, p), p);
uint32_t giant = y;
for (int a= 0; a < sqrt_p + 3; a++) {
if (baby.count(giant)) {
int b = baby[giant];
uint32_t x = a * sqrt_p + b;
return x % p;
}
giant = (uint64_t)giant * g_sqrt_p_inv % p;
}
return -1;
}
unittest {
assert (baby_step_giant_step( 3, powMod( 3, 0, 17), 17) == 0);
assert (baby_step_giant_step( 3, powMod( 3, 12, 17), 17) == 12);
assert (baby_step_giant_step(12, powMod(12, 17, 101), 101) == 17);
}
static DWORD solveWithBabyGiant(DWORD dwInput_X, DWORD dwInput_P, DWORD dwInput_A, DWORD dwInput_B)
{
for (DWORD dwRem = 1; dwRem <= MAX_DWORD; dwRem++) {
DWORD dwCandidate = baby_step_giant_step(dwInput_X, dwRem, dwInput_P);
if (MAX_DWORD != dwCandidate) {
if ((dwInput_A <= dwCandidate) && (dwCandidate <= dwInput_B)) {
return dwRem;
}
}
}
}
int main()
{
DWORD dwInput_X, dwInput_P, dwInput_A, dwInput_B;
dwInput_X = inputSDWORD();
dwInput_P = inputSDWORD();
dwInput_A = inputSDWORD();
dwInput_B = inputSDWORD();
DWORD dwAns;
if (dwInput_P <= dwInput_B - dwInput_A) {
printf("1\n");
return 0;
}
if (dwInput_B - dwInput_A <= 10000000) {
dwAns = normalSearch(dwInput_X, dwInput_P, dwInput_A, dwInput_B);
} else {
dwAns = solveWithBabyGiant(dwInput_X, dwInput_P, dwInput_A, dwInput_B);
}
printf("%d\n", dwAns);
return 0;
}
Submission Info
Submission Time |
|
Task |
D - あまり |
User |
yeye |
Language |
C++14 (GCC 5.4.1) |
Score |
100 |
Code Size |
6072 Byte |
Status |
AC |
Exec Time |
1955 ms |
Memory |
2468 KB |
Judge Result
Set Name |
Sample |
All |
Score / Max Score |
0 / 0 |
100 / 100 |
Status |
|
|
Set Name |
Test Cases |
Sample |
sample_01.txt, sample_02.txt, sample_03.txt, sample_04.txt |
All |
sample_02.txt, sample_03.txt, sample_04.txt, subtask1_00.txt, subtask1_01.txt, subtask1_02.txt, subtask1_03.txt, subtask1_04.txt, subtask1_05.txt, subtask1_06.txt, subtask1_07.txt, subtask1_08.txt, subtask1_09.txt, subtask1_10.txt, subtask1_11.txt, subtask1_12.txt, subtask1_13.txt, subtask1_14.txt, subtask1_15.txt, subtask1_16.txt, subtask1_17.txt, subtask1_18.txt, subtask1_19.txt |
Case Name |
Status |
Exec Time |
Memory |
sample_01.txt |
AC |
1 ms |
256 KB |
sample_02.txt |
AC |
1 ms |
256 KB |
sample_03.txt |
AC |
120 ms |
256 KB |
sample_04.txt |
AC |
1 ms |
256 KB |
subtask1_00.txt |
AC |
336 ms |
2468 KB |
subtask1_01.txt |
AC |
1 ms |
256 KB |
subtask1_02.txt |
AC |
1 ms |
256 KB |
subtask1_03.txt |
AC |
46 ms |
256 KB |
subtask1_04.txt |
AC |
1955 ms |
256 KB |
subtask1_05.txt |
AC |
1 ms |
256 KB |
subtask1_06.txt |
AC |
1 ms |
256 KB |
subtask1_07.txt |
AC |
1 ms |
256 KB |
subtask1_08.txt |
AC |
7 ms |
256 KB |
subtask1_09.txt |
AC |
1 ms |
256 KB |
subtask1_10.txt |
AC |
1 ms |
256 KB |
subtask1_11.txt |
AC |
283 ms |
2468 KB |
subtask1_12.txt |
AC |
1 ms |
256 KB |
subtask1_13.txt |
AC |
1 ms |
256 KB |
subtask1_14.txt |
AC |
1 ms |
256 KB |
subtask1_15.txt |
AC |
337 ms |
2340 KB |
subtask1_16.txt |
AC |
1 ms |
256 KB |
subtask1_17.txt |
AC |
1 ms |
256 KB |
subtask1_18.txt |
AC |
1 ms |
256 KB |
subtask1_19.txt |
AC |
1 ms |
256 KB |