关键:构造可以存储多项式的数据结构
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod=1e9+7;
int n, m;
vector<ll> val;
struct item //多项式
{
ll coe; //系数
map<int, int> mp; //下标为key,指数为val
item(ll coe,map<int, int> mp) : coe(coe),mp(mp){} //构造体函数
};
struct formula //加号连接的多个多项式的公式
{
vector<item> vec; //多项式数组
formula(vector<item> vec) : vec(vec){} //构造体函数
};
stack<formula> st; //栈
item item_mul(item a, item b) //各变量拼接成多项式
{
ll coe = a.coe * b.coe;
map<int, int> mp;
for(auto it : a.mp)
{
mp[it.first] = a.mp[it.first] + b.mp[it.first];
b.mp.erase(it.first);
}
for(auto it : b.mp)
{
mp[it.first] = b.mp[it.first];
}
return item(coe, mp);
}
formula formula_mul(formula a, formula b) //多项式乘法
{
vector<item> vec;
for(int i = 0; i < a.vec.size(); i++)
{
for(int j = 0; j < b.vec.size(); j++)
{
vec.push_back(item_mul(a.vec[i], b.vec[j]));
}
}
return formula(vec);
}
formula formula_add(formula a, formula b) //多项式加法
{
for(int i = 0; i < b.vec.size(); i++)
{
a.vec.push_back(b.vec[i]);
}
return a;
}
formula formula_sub(formula a, formula b) //多项式减法
{
for(int i = 0; i < a.vec.size(); i++)
{
a.vec[i].coe *= -1;
}
return formula_add(b, a);
}
ll func(formula a, int goal) //求偏导
{
ll sum = 0, mul = 1;
for(int i = 0; i < a.vec.size(); i++)
{
item t = a.vec[i];
mul = 1;
if(t.mp.find(goal) != t.mp.end()) //包含求偏导的变量的多项式,否则无意义
{
mul = (t.coe * t.mp[goal]) % mod; //系数
t.mp[goal]--; //指数
for(auto it : t.mp) //每个变量赋值
{
for(int j = 0; j < it.second; j++) //指数为j,乘j次
{
mul = (mul * val[it.first]) % mod;
}
}
sum = (sum + mul) % mod; //求和
}
}
return sum;
}
/*
ll convert(string str)
{
ll num=0;
for(int i=(str[0]=='-')?1:0;i<str.length();i++){
num*=10;
num+=str[i]-'0';
}
return (str[0]=='-')?-1*num:num;
}
*/
int main()
{
cin >> n >> m;
getchar();
string str, s;
getline(cin, str);
stringstream sin(str); //将str中的字符串取出到s(按每个空格)
while(sin >> s)
{
if(s == "+" || s == "-" || s == "*") //符号op,取出两个数作b op a
{
formula a = st.top();st.pop();
formula b = st.top();st.pop();
if(s == "*")
{
st.push(formula_mul(b,a));
}
else if(s == "+")
{
st.push(formula_add(b, a));
}
else
{
st.push(formula_sub(a, b));
}
}
else
{
map<int, int> mp;
vector<item> vec;
if(s[0] == 'x') //变量,取出下标,指数为1
{
s = s.substr(1);
mp[stol(s)] = 1;
//mp[convert(s.substr(1,s.length()-1))]=1;
vec.push_back(item(1, mp));
}
else //常数,下标和指数均为0
{
vec.push_back(item(stol(s), mp));
//vec.push_back(item(convert(s),mp));
}
st.push(formula(vec));
}
}
for(int i = 0; i < m; i++)
{
ll v;
for(int j = 0; j < n + 1; j++) //第一个为求偏导的变量,后面为变量的值
{
cin >> v;
val.push_back(v);
}
ll ans = func(st.top(), val[0]); //栈顶剩余的最后一个公式为最终公式式,对val[0]求偏导
cout << ((ans < 0) ? ans + mod : ans) << endl; //负数要转化为正数
val.clear();
}
return 0;
}