#P6959. [NEERC 2017] Hack
[NEERC 2017] Hack
题目描述
Heidi is analyzing a peculiar device. This device takes an a as input and computes using thefollowing pseudocode and some integers and stored in this device:
modPow(a, d, n) {
r = 1;
for (i = 0; i < 60; ++i) {
if ((d & (1 << i)) != 0) {
r = r * a % n;
}
a = a * a % n;
}
}
Note that the pseudocode assumes arbitrary sized integers, denotes bitwise shift left, & denotes bitwise
and, and % denotes modulo.
The device does not tell Heidi the result of the computation. However, Heidi can measure how long does the computation take. She knows that only multiplication modulo (lines and in the above pseudocode) takes any measurable amount of time, all other lines can be assumed to take nanoseconds.
Moreover, she knows that it takes nanoseconds to multiply by modulo , where is the number of bits in the binary representation of without leading zeros, or more formally $\text{bits(x)} = ⌈\log_2 (x + 1)⌉.
Heidi knows the integer but does not know the integer . She wants to find by feeding the device different integers a as input and measuring the time the computation takes for each a .
She knows that and were chosen in the following way: first, two prime numbers and with bits in binary representation (in other words, between and were picked independently and uniformly at random. Then the number was computed as . Then the number
was computed. Then was picked uniformly at random between and inclusive, such that it is coprime with .
Interaction Protocol
First, the testing system writes the integer -- the modulo used by the device. Note that and the hidden number are guaranteed to have been generated according to the procedure described above.
Your solution shall print requests of two types:
-
“? a” tells to feed a as input to the device. a must be an integer between and inclusive. The testing system responds with the time it took the device to compute
modPow(a , d , n)in nanoseconds. -
“! d” tells the value of that your program has determined.
Don't forget to flush the output after each request!
Your solution must issue exactly one request of the second type, which must be the last request, and the solution must terminate gracefully after issuing it.
Your solution is allowed to issue at most requests of the first type.
Your solution will be run on testcases, working with one pair per run. For each testcase the numbers and are fixed and were generated using the procedure described above. The example below
was not generated in that manner and thus will not be used for testing your solution; it only serves to illustrate the input/output format and provide a sanity check for your calculation of the computation time.
15
980
293
? 3
? 8
! 5