#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;
struct node
{
char ch;
ll num;
int type;//0 运算 1 变量 2 表示常量
int l, r;
} a[2000];
int n, m, cnt, dao;
int b[150];
string f;
int judge(char ch)
{
return ch == '+' || ch == '-' || ch == '*';
}
void build()//建立表达式树
{
istringstream ss(f);
string temp;
stack<int> s;
while (ss >> temp)
{
//cout << "分割字符为" << temp << endl;
if (temp.size() == 1 && judge(temp[0]))
{
a[cnt].type = 0;
a[cnt].ch = temp[0];
a[cnt].r = s.top();
s.pop();
a[cnt].l = s.top();
s.pop();
s.push(cnt);
cnt++;
}
else if (temp[0] == 'x')
{
a[cnt].type = 1;
a[cnt].num = stol(temp.substr(1, temp.size()));
//cout << a[cnt].num << endl;
s.push(cnt);
cnt++;
}
else//常数
{
a[cnt].type = 2;
a[cnt].num = stol(temp);
//cout << a[cnt].num << endl;
s.push(cnt);
cnt++;
}
}
//cout << s.size() << " " << cnt << endl;
//cout << last << endl;
}
ll cal(int x, bool check) //计算偏导 1 求 2 原来
{
//cout << "进入计算 " << x << endl;
if (a[x].type == 1)
{
if (check)
{
if (dao != a[x].num)
return 0;
else
return 1;
}
else
return b[a[x].num];
}
else if (a[x].type == 2)
{
if (check)
return 0;
else
return a[x].num;
}
else
{
ll l, r;
if (a[x].ch == '+')
{
if (check)
{
l = cal(a[x].l, 1) % mod;
r = cal(a[x].r, 1) % mod;
return (l + r) % mod;
}
else
return (cal(a[x].l, 0) % mod + cal(a[x].r, 0) % mod) % mod;
}
else if (a[x].ch == '-')
{
if (check)
return cal(a[x].l, 1) % mod - cal(a[x].r, 1) % mod;
else
return cal(a[x].l, 0) % mod - cal(a[x].r, 0) % mod;
}
else
{
if (check)
return (cal(a[x].l, 1) * cal(a[x].r, 0) % mod + cal(a[x].l, 0) * cal(a[x].r, 1) % mod) % mod;
else
return ((cal(a[x].l, 0) % mod ) * (cal(a[x].r, 0) % mod)) % mod;
}
}
return 0;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> m;
cin.ignore();
getline(cin, f);
build();
// for (int i = 0; i < cnt; i++)
// {
// if (a[i].type == 1)
// {
// cout << 1 << " " << a[i].num << endl;
// }
// else if (a[i].type == 2)
// {
// cout << 2 << " " << a[i].num << endl;
// }
// else
// {
// cout << 3 << " " << a[i].ch << " " << a[i].l << " " << a[i].r << endl;
// }
// }
for (int i = 0; i < m; i++)
{
cin >> dao;
for (int i = 1; i <= n; i++)
cin >> b[i];
ll res = cal(cnt - 1, 1);
cout << (res + mod) % mod << endl;
}
return 0;
}
CSP20230903 梯度求解满分代码
最新推荐文章于 2024-03-22 16:47:40 发布