题目链接
刚开始完全没想法,索性用导数定义求解,将自变量和自变量减0.000001带入求函数值,用两个函数值之差除以0.000001,最后结果再四舍五入。只得了50分。
后来想到最适合求导的就是多项式形式,一个数组就是一个多项式,下标就是一项的指数,值就是一项的系数。后缀表达式求值的方法也可以用来算多项式。
不过还是没AC,只有80分,不知道问题在哪。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//从字符串得到逆波兰
vector<string> getfi(string s) {
vector<string> fi;
stringstream ss(s);
string item;
while (getline(ss, item, ' ')) {
if (!item.empty()) {
fi.emplace_back(item);
}
}
return fi;
}
//把所有其他数字带入逆波兰,xi是X的序号
vector<string> getni(vector<string> fi, int xi, vector<ll> xs) {
for (int i = 0; i < fi.size(); i++) {
string fii = fi[i];
if (fii[0] == 'x') {
fii.erase(fii.begin());
int fiii = stoi(fii);
fiii--;
//如果不是要求的未知数
if (fiii != xi) {
fi[i] = to_string(xs[fiii]);
}else {
fi[i] = "x";
}
}
}
return fi;
}
//两个多项式计算
//多项式以数组存储,数组下标即是指数,数据即是系数。
vector<ll> cal(vector<ll> v1, vector<ll> v2, string op) {
int n1 = v1.size(), n2 = v2.size();
vector<ll> re;
if (op == "+") {
re.resize(max(n1, n2));
for (int i = 0; i < re.size(); i++) {
ll v11 = 0, v22 = 0;
if (i < v1.size())v11 = v1[i];
if (i < v2.size())v22 = v2[i];
re[i] = v11 + v22;
}
}
if (op == "-") {
re.resize(max(n1, n2));
for (int i = 0; i < re.size(); i++) {
ll v11 = 0, v22 = 0;
if (i < v1.size())v11 = v1[i];
if (i < v2.size())v22 = v2[i];
re[i] = v11 - v22;
}
}
if (op == "*") {
re.resize(n1 + n2 - 1);
for (int i = 0; i < n1; i++) {
for (int j = 0; j < n2; j++) {
re[i + j] = re[i + j] + v1[i] * v2[j];
}
}
}
return re;
}
//对整个多项式求导,系数乘以指数为新的系数,指数减一为新的指数
ll dao(vector<ll> y, ll x) {
int n = y.size();
ll re = 0;
for (int i = 0; i < n - 1; i++) {
re += (y[i + 1] * (i + 1)) * pow(x, i);
}
return re;
}
//把逆波兰表达式计算为一个多项式形式
vector<ll> count(vector<string> ni) {
int n = ni.size();
stack<vector<ll>> ns;
for (int i = 0; i < n; i++) {
string nx = ni[i];
if (nx == "+") {
vector<ll> v1 = ns.top();
ns.pop();
vector<ll> v2 = ns.top();
ns.pop();
ns.push(cal(v1, v2, "+"));
}else if (nx == "-") {
vector<ll> v2 = ns.top();
ns.pop();
vector<ll> v1 = ns.top();
ns.pop();
ns.push(cal(v1, v2, "-"));
}else if (nx == "*") {
vector<ll> v1 = ns.top();
ns.pop();
vector<ll> v2 = ns.top();
ns.pop();
ns.push(cal(v1, v2, "*"));
}else {
if (nx == "x") {
vector<ll>t = { 0,1 };
ns.push(t);
}
else {
vector<ll>t = { stoll(nx) };
ns.push(t);
}
}
}
return ns.top();
}
int main() {
int n, m;
cin >> n >> m;
string s;
cin.get();
getline(cin, s);
long long po = pow(10, 9) + 7;
vector<string> fi = getfi(s);
for (int i = 0; i < m; i++) {
ll xi;
cin >> xi;
xi--;
vector<ll> xs;
for (int j = 0; j < n; j++) {
ll xj;
cin >> xj;
xs.emplace_back(xj);
}
vector<string> ni = getni(fi, xi, xs);
vector<ll> y = count(ni);
ll re = dao(y, xs[xi]);
re = re % po;
if (re < 0)re += po;
cout << re << endl;
}
return 0;
}