当前位置: 首页 > news >正文

梯度求解 第31次CCF-CSP计算机软件能力认证

大佬题解

如果你有深度学习基础的话,那么这道题就很容易想到了,根据深度学习的计算规则,想要计算梯度,先要构建一张计算图,使用二叉树实现,因为已经给了逆波兰表达式,使用栈就可以构建出计算图(二叉树),然后forward正向传播,正向传播的目的是计算出每个结点对应的中间值用来反向传播使用,然后backward反向传播,递归求解到叶子结点然后返回即可。
AC代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 1e9 + 7;/*----------------- 结点 -----------------*/
struct Node {string op;int l = -1, r = -1;Node() {}Node(string o) :op(std::move(o)) {}Node(string o, int L, int R) :op(std::move(o)), l(L), r(R) {}
};
vector<Node> tree;/*----------------- 工具 -----------------*/
inline bool isOp(const string& s) { return s == "+" || s == "-" || s == "*" || s == "/"; }
inline bool isNumber(const string& s) { return !s.empty() && (isdigit(s[0]) || (s[0] == '-' && s.size() > 1)); }
ll mod_add(ll a, ll b) { a += b; if (a >= MOD) a -= MOD; if (a < 0) a += MOD; return a; }
ll mod_mul(ll a, ll b) { return (a % MOD) * (b % MOD) % MOD; }/*----------------- build -----------------*/
int build_tree(const vector<string>& pf) {stack<int> st;for (const string& tok : pf) {if (isOp(tok)) {int r = st.top(); st.pop();int l = st.top(); st.pop();int id = tree.size();tree.emplace_back(tok, l, r);st.push(id);}else {int id = tree.size();tree.emplace_back(tok);st.push(id);}}return st.top();
}/*----------------- forward -----------------*/
ll eval(int u, vector<ll>& val, const vector<ll>& varVal) {if (val[u] != -1) return val[u];const Node& nd = tree[u];if (nd.l == -1) {                              // 叶子if (isNumber(nd.op))val[u] = (stoll(nd.op) % MOD + MOD) % MOD;else {int idx = stoi(nd.op.substr(1)) - 1; // 关键修正 ↓↓↓val[u] = varVal[idx];}}else {ll L = eval(nd.l, val, varVal);ll R = eval(nd.r, val, varVal);if (nd.op == "+") val[u] = mod_add(L, R);else if (nd.op == "-") val[u] = mod_add(L, -R);else if (nd.op == "*") val[u] = mod_mul(L, R);}return val[u];
}/*----------------- backward -----------------*/
ll backward(int u, int target, const vector<ll>& val) {const Node& nd = tree[u];if (nd.l == -1) {return (!isNumber(nd.op) && (stoi(nd.op.substr(1)) - 1) == target) ? 1 : 0; // 关键修正 ↓↓↓}ll dL = backward(nd.l, target, val);ll dR = backward(nd.r, target, val);ll L = val[nd.l];ll R = val[nd.r];if (nd.op == "+") return mod_add(dL, dR);if (nd.op == "-") return mod_add(dL, -dR);if (nd.op == "*") return mod_add(mod_mul(dL, R), mod_mul(L, dR));return 0;
}/*----------------- main -----------------*/
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int n, m;cin >> n >> m;cin.ignore();string line, tok;getline(cin, line);istringstream iss(line);vector<string> postfix;while (iss >> tok) postfix.push_back(tok);tree.clear();int root = build_tree(postfix);for (int q = 0; q < m; ++q) {int idx; cin >> idx; --idx;          // 改成 0‑basevector<ll> varVal(n);for (int i = 0; i < n; ++i) {cin >> varVal[i];varVal[i] = (varVal[i] % MOD + MOD) % MOD;}vector<ll> val(tree.size(), -1);eval(root, val, varVal);cout << backward(root, idx, val) % MOD << '\n';}return 0;
}

相关文章:

  • 大模型应用案例:主动提问式的 AI 面试官(接入 DeepSeek)
  • 普罗米修斯Prometheus监控安装(mac)
  • 模拟实现strcmp,strcpy,strlen,strcat,strstr
  • Dijkstra 算法入门笔记 (适用于算法竞赛初学者) - C++ 代码版
  • 【上位机——MFC】消息映射机制
  • AI日报 - 2025年04月21日
  • SQL之DML(查询语句:select、where)
  • 数据通信学习笔记之OSPF的区域
  • AIGC赋能插画创作:技术解析与代码实战详解
  • 自由的控件开发平台:飞帆中使用 css 和 js 库
  • LeetCode283.移动零
  • HTTP 1.0 和 2.0 的区别
  • 阿拉丁神灯-第16届蓝桥第4次STEMA测评Scratch真题第2题
  • Redis 缓存—处理高并发问题
  • 对于网络资源二级缓存的简单学习
  • 【嵌入式人工智能产品开发实战】(二十一)—— 政安晨:源码搭建小智AI嵌入式终端的后端服务(服务器)环境 - 助力嵌入式人工智能开发
  • 测试基础笔记第七天
  • [FPGA]设计一个DDS信号发生器
  • 每天学一个 Linux 命令(28):ln
  • CentOS stream 中部署Zabbix RPM软件包公钥验证错误
  • 南部战区回应菲护卫艇非法侵入中国黄岩岛领海:依法警告驱离
  • 重点并不在于设计更聪明的机器,而在于开发宇宙技术的多样性
  • 西藏艺术来到黄浦江畔,“隐秘之门”艺术展外滩三号开幕
  • 经济日报:从三个变化看外贸破局之道
  • 美国佛罗里达州立大学枪击事件已致2人死亡
  • A股三大股指涨跌互现:房地产板块大幅上涨,两市成交9995亿元