#include <bits/stdc++.h>
#include <sstream>
using namespace std;
typedef long long LL;
const int N = 120;
const int MOD = 1e9 + 7;
struct exps
{
vector<string> a[N]; // x^i的系数
int i; // 最高次幂
};
vector<string> eq;
stack<exps> eq2;
unordered_map<string, int> f;
int val[N];
int n, m;
void get_idx(string x)
{
if (f[x]) return;
int idx = 0;
for (int i = 1; i < x.size(); i++)
idx = idx * 10 + x[i] - '0';
f[x] = idx;
}
void _proc(string op, int x)
{
exps x1, x2, nx;
x2 = eq2.top(); eq2.pop();
x1 = eq2.top(); eq2.pop();
if (op == "+" || op == "-")
{
nx.i = max(x1.i, x2.i);
for (int i = 0; i <= max(x1.i, x2.i); i++)
{
if (!x1.a[i].size() && !x2.a[i].size()) continue;
nx.a[i] = x1.a[i];
if (!x1.a[i].size()) nx.a[i].push_back("0");
nx.a[i].insert(nx.a[i].end(), x2.a[i].begin(), x2.a[i].end());
if (x2.a[i].size()) nx.a[i].push_back(op);
}
}
else // 乘法
{
nx.i = x1.i + x2.i;
for (int i = 0; i <= x1.i; i++)
{
for (int j = 0; j <= x2.i; j++)
{
bool flag = false;
if (nx.a[i + j].size()) flag = true;
if (x1.a[i].size() && x2.a[j].size())
{
nx.a[i + j].insert(nx.a[i + j].end(), x1.a[i].begin(), x1.a[i].end());
nx.a[i + j].insert(nx.a[i + j].end(), x2.a[j].begin(), x2.a[j].end());
nx.a[i + j].push_back(op);
if (flag) nx.a[i + j].push_back("+");
}
}
}
}
eq2.push(nx);
}
void proc(int x)
{
for (auto t : eq)
{
if (t == "+" || t == "-" || t == "*") _proc(t, x);
else
{
if (f[t] == x)
{
exps e;
e.a[1] = {"1"};
e.i = 1;
eq2.push(e);
}
else
{
exps e;
e.a[0] = {t};
e.i = 0;
eq2.push(e);
}
}
}
}
LL str2num(string s)
{
bool isneg = false;
int i = 0;
if (s[0] == '-')
{
isneg = true;
i++;
}
LL res = 0;
for (; i < s.size(); i++)
{
res = res * 10 + s[i] - '0';
}
if (isneg) res = -res;
return res;
}
LL get_val(vector<string> e)
{
stack<LL> stk;
for (auto t : e)
{
if (t == "+" || t == "-" || t == "*")
{
LL x2 = stk.top(); stk.pop();
LL x1 = stk.top(); stk.pop();
LL res;
if (t == "+") res = (x1 + x2) % MOD;
else if (t == "-") res = (x1 - x2) % MOD;
else res = x1 * x2 % MOD;
stk.push(res);
}
else
{
if (t[0] == 'x') stk.push(val[f[t]]);
else stk.push(str2num(t));
}
}
if (stk.size() == 1) return stk.top();
return -1;
}
LL qmi(int m, int k, int p)
{
LL res = 1 % p, t = m;
while (k)
{
if (k & 1) res = res * t % p;
t = t * t % p;
k >>= 1;
}
return res;
}
LL cal(int x)
{
LL res = 0;
if (eq2.size() != 1) return -1;
else
{
exps e = eq2.top();
eq2.pop();
for (int i = 1; i <= e.i; i++)
{
if (e.a[i].size())
res += i * qmi(val[x], i - 1, MOD) % MOD * get_val(e.a[i]) % MOD;
res %= MOD;
}
}
return (res + MOD) % MOD;
}
int main()
{
scanf("%d%d", &n, &m);
getchar();
string line;
getline(cin, line);
stringstream ssin(line);
string t;
while (ssin >> t)
{
if (t[0] == 'x') get_idx(t);
eq.push_back(t);
}
while (m--)
{
int x;
scanf("%d", &x);
for (int i = 1; i <= n; i++)
{
int v;
scanf("%d", &v);
val[i] = v;
}
proc(x);
printf("%lld\n", cal(x));
}
return 0;
}
优化
按照算数表达式树的结构,递归求导