#P6959. [NEERC2017] Hack
[NEERC2017] 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.
题目大意
有如下的一个程序来计算 ,(是常数)
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;
}
}
其中,计算 (上述伪代码中的第 行和第 行)需要消耗 纳秒, 是 的二进制表示中不带前导零的位数,更正式的说,为 ,其他指令可以认为不需要任何时间。
你知道 ,但不知道 , 你可以通过不超过 次询问对于 计算 所用纳秒数。
正式数据中, 的生成方式如下:随机挑选两个 的质数 ,,而 为在 随机挑选的,与 互质的数
这是一道交互题
首先,将给出整数
有两种指令可用:
“? a”询问对于正整数 计算 所用纳秒数。要求。返回所用的纳秒数
“! d”表示确定了 的值并提交,你的程序应当在此后结束。
15
980
293
? 3
? 8
! 5