Descripción del Título
SLON es un estudiante travieso. Para calmarlo, la maestra le dio un problema de matemáticas:
Dada la expresión A, A contiene variables x y +, -, *, (,) estos símbolos, los paréntesis aparecen en pares, un operador aritmético corresponde a dos operandos, no pueden aparecer (-5) o (4+ -5) Etc. , el signo de multiplicación no se puede omitir, y x en la expresión A solo puede ser una expresión de primer orden:
Expresión razonable: A = 5 + x ∗ (3 + 2) o x + 3 ∗ x + 4 ∗ (5 + 3 ∗ (2 + x − 2 ∗ x)).
Expresión irrazonable: A = 5 ∗ (3 + x ∗ (3 + x)) o x ∗ (x + x ∗ (1 + x)).
Cuando A% M == P, el menor x
ingresar
Ingrese una expresión A en la primera línea, (1 ≤ | A | ≤ 100000).
Ingrese dos números enteros P (0 ≤ P ≤ M −1) y M (1 ≤ M ≤ 1000000) en la segunda línea.
Producción
Genere el valor de x no negativo más pequeño (0 ≤ x ≤ 1000000).
Entrada de muestra 1
5 + 3 + x
9 10
Salida de muestra 1
1
Entrada de muestra 2
20 + 3 + x
0 5
Salida de muestra 2
2
Entrada de muestra 3
3 * (x + (x + 4) * 5)
1 7
Salida de muestra 3
1
Ideas
Esta pregunta se hizo originalmente con un sufijo, amigos que son firmes en moralidad, por favor vea la solución correcta del maestro.
Primero pensemos: A es una expresión de primer orden (una función).
Como se mencionó en matemáticas de la escuela secundaria, una función lineal se puede expresar como kx + b. Por ejemplo, el ejemplo uno se puede expresar como x + 8, el ejemplo dos se puede expresar como x + 23 y el ejemplo tres se puede expresar como 18x +60.
Entonces solo se requieren k y b, y como 0 ≤ x ≤ 1000000, puede enumerarse violentamente (también puede usar la expansión de Europa, que es más rápida).
El siguiente paso es la esencia de esta pregunta: reduce la expresión compleja A del ladrón a kx + b.
Primero podemos usar la idea de bloque: debido a que la suma y la resta es el cálculo final, entonces divida A en varias partes y sume la suma, luego, ¿puede cada parte expresarse en la forma de kx + b? (Obviamente)
Use la función ins () para cambiar una fórmula a kx + b. Dado que no se sabe en cuántas partes se divide A, es mejor usar un vector de matriz dinámica para almacenar cada parte. Cuando se encuentra un número o una x, si está precedido por "+" o "-", súmelo (añade un signo menos para restar); si va precedido por "*", multiplica el último dígito de la matriz por él.
Cuando encuentra "(", ingresa de forma recursiva, convierte la expresión ins () entre corchetes en a kx + b, y luego realiza las mismas operaciones que antes.
Esta operación de multiplicación necesita una discusión especial: cuando se multiplican dos kx + b, uno de los k es cero (porque el problema garantiza que el número de x es 1), por lo que equivale a multiplicar k y b en un lado por a constante.
Un punto más, debido a que el título no indica qué tan grande es el número en A, puede estallar mucho tiempo, debe modulo m mientras opera, sin afectar el resultado.
Para operaciones y detalles específicos, consulte el código a continuación
Código
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#define ll long long
using namespace std;
ll k,b,p,m;
int l;
string ss;
struct itn{
ll k,b;
itn(){}itn(ll K,ll B){
k=(K+m)%m,b=(B+m)%m;
}
itn operator+(const itn&c){return itn(k+c.k,b+c.b);}
itn operator*(const itn&c){
if(k==0)return itn(c.k*b,c.b*b);
else return itn(k*c.b,b*c.b);
}
};
char s;
itn ins(){
vector<itn>g;
itn an=itn(0,0);
int f=0;
while(l<=ss.length()&&s&&s!=')'){
if(s>='0'&&s<='9'){
ll x=0;
while(l<=ss.length()&&s>='0'&&s<='9')x=(x*10+s-'0')%m,s=ss[l++];//l=ss.length()时返回的为'\0'
if(f==0)g.push_back(itn(0,x));
else if(f==1)g.push_back(itn(0,-x));
else {
int o=g.size()-1;
g[o]=g[o]*itn(0,x);
}
}
else if(s=='x'){
if(f==0)g.push_back(itn(1,0));
else if(f==1)g.push_back(itn(-1,0));
else {
int o=g.size()-1;
g[o]=g[o]*itn(1,0);
}
if(l<=ss.length())s=ss[l++];
}
else if(s=='+'){
f=0;
if(l<=ss.length())s=ss[l++];
}
else if(s=='-'){
f=1;
if(l<=ss.length())s=ss[l++];
}
else if(s=='*'){
f=2;
if(l<=ss.length())s=ss[l++];
}
else if(s=='('){
if(l<=ss.length())s=ss[l++];
itn x=ins();
if(f==0)g.push_back(x);
else if(f==1)g.push_back(itn(-x.k,-x.b));
else {
int o=g.size()-1;
g[o]=g[o]*x;
}
if(l<=ss.length())s=ss[l++];
}
}
for(int i=0;i<g.size();i++)an=an+g[i];
return an;
}
int main()
{
//freopen("slon.in","r",stdin);
//freopen("slon.out","w",stdout);
cin>>ss;
scanf("%lld%lld",&p,&m);
s=ss[l++];
itn a=ins();
k=a.k,b=a.b;
//printf("A=%lldx+%lld\n",k,b);
for(ll x=0;x<=1000000;x++)
if(x*k+b>=0&&(x*k+b)%m==p){
printf("%lld\n",x);
return 0;
}
puts("100000");
return 0;
}