CF39G.Inverse Function

提高+/省选-

通过率:0%

时间限制:5.00s

内存限制:64MB

AC君温馨提醒

该题目为【codeforces】题库的题目,您提交的代码将被提交至codeforces进行远程评测,并由ACGO抓取测评结果后进行展示。由于远程测评的测评机由其他平台提供,我们无法保证该服务的稳定性,若提交后无反应,请等待一段时间后再进行重试。

题目描述

Petya wrote a programme on C++ that calculated a very interesting function f(n). Petya ran the program with a certain value of n and went to the kitchen to have some tea. The history has no records concerning how long the program had been working. By the time Petya returned, it had completed the calculations and had the result. However while Petya was drinking tea, a sly virus managed to destroy the input file so that Petya can't figure out for which value of n the program was run. Help Petya, carry out the inverse function!

Mostly, the program consists of a function in C++ with the following simplified syntax:

  • function ::= int f(int n) {operatorSequence}
  • operatorSequence ::= operator | operator operatorSequence
  • operator ::= return arithmExpr; | if (logicalExpr) return arithmExpr;
  • logicalExpr ::= arithmExpr > arithmExpr | arithmExpr < arithmExpr | arithmExpr == arithmExpr
  • arithmExpr ::= sum
  • sum ::= product | sum + product | sum - product
  • product ::= multiplier | product * multiplier | product / multiplier
  • multiplier ::= n | number | f(arithmExpr)
  • number ::= 0|1|2|... |32767

The whitespaces in a operatorSequence are optional.

Thus, we have a function, in which body there are two kinds of operators. There is the operator "return arithmExpr;" that returns the value of the expression as the value of the function, and there is the conditional operator "if (logicalExpr) return arithmExpr;" that returns the value of the arithmetical expression when and only when the logical expression is true. Guaranteed that no other constructions of C++ language — cycles, assignment operators, nested conditional operators etc, and other variables except the n parameter are used in the function. All the constants are integers in the interval [0..32767].

The operators are performed sequentially. After the function has returned a value other operators in the sequence are not performed. Arithmetical expressions are performed taking into consideration the standard priority of the operations. It means that first all the products that are part of the sum are calculated. During the calculation of the products the operations of multiplying and division are performed from the left to the right. Then the summands are summed, and the addition and the subtraction are also performed from the left to the right. Operations ">" (more), "<" (less) and "==" (equals) also have standard meanings.

Now you've got to pay close attention! The program is compiled with the help of 15-bit Berland C++ compiler invented by a Berland company BerSoft, that's why arithmetical operations are performed in a non-standard way. Addition, subtraction and multiplication are performed modulo 32768 (if the result of subtraction is negative, then 32768 is added to it until the number belongs to the interval [0..32767]). Division "/" is a usual integer division where the remainder is omitted.

Examples of arithmetical operations:

Guaranteed that for all values of n from 0 to 32767 the given function is performed correctly. That means that:

1. Division by 0 never occures.

2. When performing a function for the value n = N recursive calls of the function f may occur only for the parameter value of 0, 1, ..., N - 1. Consequently, the program never has an infinite recursion.

3. As the result of the sequence of the operators, the function always returns a value.

We have to mention that due to all the limitations the value returned by the function f is independent from either global variables or the order of performing the calculations of arithmetical expressions as part of the logical one, or from anything else except the value of n parameter. That's why the f function can be regarded as a function in its mathematical sense, i.e. as a unique correspondence between any value of n from the interval [0..32767] and a value of f(n) from the same interval.

Given the value of f(n), and you should find n. If the suitable n value is not unique, you should find the maximal one (from the interval [0..32767]).

佩佳用 C++ 编写了一个计算非常有趣的函数 $ f(n) $ 的程序。佩佳以某个特定的 $ n $ 值运行了该程序,然后去厨房喝茶。历史记录中并未说明该程序运行了多长时间。当佩佳返回时,程序已完成了全部计算并得到了结果。然而,在佩佳喝茶期间,一个狡猾的病毒破坏了输入文件,导致佩佳无法确定程序当时运行所用的 $ n $ 值。请帮助佩佳完成逆运算!

该程序主体是一个符合如下简化语法的 C++ 函数:

  • function ::= int f(int n) {operatorSequence}
  • operatorSequence ::= operator | operator operatorSequence
  • operator ::= return arithmExpr; | if (logicalExpr) return arithmExpr;
  • logicalExpr ::= arithmExpr > arithmExpr | arithmExpr < arithmExpr | arithmExpr == arithmExpr
  • arithmExpr ::= sum
  • sum ::= product | sum + product | sum - product
  • product ::= multiplier | product * multiplier | product / multiplier
  • multiplier ::= n | number | f(arithmExpr)
  • number ::= 0|1|2|...|32767

在 operatorSequence 中,空白字符是可选的。

因此,我们面对的是一个函数,其函数体内仅包含两类操作符:一类是 return arithmExpr; 操作符,它将算术表达式的值作为函数的返回值;另一类是条件操作符 if (logicalExpr) return arithmExpr;,它仅当逻辑表达式为真时才返回对应算术表达式的值。保证该函数中不使用 C++ 语言的其他构造——例如循环、赋值操作符、嵌套的条件操作符等,也不使用除参数 $ n $ 以外的任何其他变量。所有常量均为区间 [0..32767][0..32767] 内的整数。

操作符按顺序依次执行。一旦函数返回某个值,后续的操作符便不再执行。算术表达式的计算遵循标准运算优先级规则:即首先计算作为和式组成部分的所有乘积;在计算乘积时,乘法与除法从左至右依次进行;随后对各项求和,加法与减法也从左至右依次进行。关系运算符 >(大于)、<(小于)及 ==(等于)具有标准语义。

现在请注意!该程序由一家名为 BerSoft 的伯兰公司所发明的 15 位伯兰 C++ 编译器 编译,因此算术运算以一种非标准方式进行:加法、减法和乘法均对 $ 32768 $ 取模(若减法结果为负,则不断加上 $ 32768 $,直至结果落入区间 [0..32767][0..32767]);而除法 / 是常规的整数除法(舍去余数)。

算术运算示例如下:

保证:对于所有 $ n \in [0..32767] $,给定函数均能正确执行。这意味着:

  1. 永远不会发生除零错误;
  2. 当以 $ n = N $ 运行该函数时,函数 $ f $ 的递归调用仅可能发生在参数取值为 $ 0, 1, \dots, N-1 $ 的情形下。因此,程序绝不会陷入无限递归;
  3. 经过一系列操作符执行后,函数总会返回一个值。

还需特别指出:由于上述所有限制条件,函数 $ f $ 的返回值完全独立于全局变量、逻辑表达式中算术子表达式的计算顺序,以及除参数 $ n $ 外的任何其他因素。因此,函数 $ f $ 可被视作数学意义上的函数,即它建立了区间 [0..32767][0..32767] 内每个 $ n $ 值与同一区间内唯一对应的 $ f(n) $ 值之间的一一映射关系。

现给定 $ f(n) $ 的值,请你求出对应的 $ n $。若满足条件的 $ n $ 不唯一,则应找出其中最大的一个(在区间 [0..32767][0..32767] 内)。

输入格式

The first line has an integer f(n) from the interval [0..32767]. The next lines have the description of the function f. In the description can be found extra spaces and line breaks (see the examples) which, of course, can’t break key words int, if, return and numbers. The size of input data can’t exceed 100 bytes.

第一行包含一个整数 f(n)f(n),取值范围为 [0..32767][0..32767]。接下来的若干行描述函数 ff。该描述中可能含有额外的空格和换行符(参见示例),但这些空格和换行符当然不能将关键字 int、if、return 以及数字打断。输入数据的大小不得超过 100 字节。

输出格式

Output a single number — the answer to the problem. If there’s no answer, output "-1" (without quotes).

输出一个数字——该问题的答案。如果无解,输出“-1”(不含引号)。

输入输出样例

  • 输入#1

    17
    int f(int n)
    {
    if (n &lt; 100) return 17;
    if (n &gt; 99) return 27;
    }

    输出#1

    99
  • 输入#2

    13
    int f(int n)
    {
    if (n == 0) return 0;
    return f(n - 1) + 1;
    }

    输出#2

    13
  • 输入#3

    144
    int f(int n)
    {
    if (n == 0) return 0;
    if (n == 1) return n;
    return f(n - 1) + f(n - 2);
    }

    输出#3

    24588

输入解题思路,AI测评打分。不知道怎么写?

首页