您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
RationalModConverter の userjs 版です.Mod をとる問題の問題文・サンプルに含まれる大きな値を,有理数に変換して横に表示します.
// ==UserScript== // @name rational-mod-converter-userjs // @namespace iilj // @version 2022.6.0 // @description RationalModConverter の userjs 版です.Mod をとる問題の問題文・サンプルに含まれる大きな値を,有理数に変換して横に表示します. // @author iilj // @license MIT // @supportURL https://github.com/iilj/RationalModConverterUserJS/issues // @match https://atcoder.jp/contests/*/tasks/* // @match https://yukicoder.me/problems/* // @grant none // ==/UserScript== /** * Rational reconstruction (mathematics) - Wikipedia * https://en.wikipedia.org/wiki/Rational_reconstruction_(mathematics) **/ const reconstruct = (n, mod) => { let v = [mod, 0]; let w = [n, 1]; while (w[0] * w[0] * 2 > mod) { const q = Math.floor(v[0] / w[0]); const z = [v[0] - q * w[0], v[1] - q * w[1]]; v = w; w = z; } if (w[1] < 0) { w[0] *= -1; w[1] *= -1; } return w; }; class RationalModConverter { constructor() { let root = null; if (location.hostname === 'atcoder.jp') { root = document.getElementById('task-statement'); } else if (location.hostname === 'yukicoder.me') { root = document.getElementById('content'); } if (root === null) return; this.mod = this.searchMod(root); if (this.mod === undefined) return; this.dfsNodes(root); } searchMod(root) { let mod = undefined; const scripts = root.querySelectorAll('var > script'); for (let i = 0; i < scripts.length; i++) { if ((mod = this.serarchModSub(scripts[i])) !== undefined) return mod; } const mjxs = root.querySelectorAll('mjx-assistive-mml'); for (let i = 0; i < mjxs.length; i++) { if ((mod = this.serarchModSub(mjxs[i])) !== undefined) return mod; } const katex = root.querySelectorAll('span.katex-html'); for (let i = 0; i < katex.length; i++) { if ((mod = this.serarchModSub(katex[i])) !== undefined) return mod; } return undefined; } serarchModSub(element) { const txt = element.textContent; if (txt === null) return undefined; const ret = RationalModConverter.str2mod.find(([pat]) => txt.indexOf(pat) !== -1); if (ret === undefined) return undefined; return ret[1]; } dfsNodes(root) { if (root.classList.contains(RationalModConverter.SPAN_CLASS_NAME)) return; root.childNodes.forEach((childNode) => { switch (childNode.nodeName) { case 'SPAN': case 'DIV': case 'P': case 'PRE': case 'UL': case 'OL': case 'LI': case 'SECTION': this.dfsNodes(childNode); break; case '#text': this.rewriteTextNode(childNode, root); break; } }); } rewriteTextNode(node, parent) { if (this.mod === undefined) return; if (node.nodeValue === null) return; const match = RationalModConverter.re.exec(node.nodeValue); if (match !== null) { const len = match.index + match[0].length; const nextNode = node.splitText(len); const parsed = parseInt(match[0]); if (parsed < this.mod && parsed * parsed * 2 > this.mod) { const w = reconstruct(parsed, this.mod); const newSpan = document.createElement('span'); newSpan.innerText = w[1] === 1 ? ` ${w[0]}` : ` ${w[0]}/${w[1]}`; newSpan.style.color = 'red'; newSpan.style.marginRight = '0.5rem'; newSpan.classList.add(RationalModConverter.SPAN_CLASS_NAME); parent.insertBefore(newSpan, nextNode); // console.log(parsed, w); } this.rewriteTextNode(nextNode, parent); } } } RationalModConverter.re = /\d+/; RationalModConverter.SPAN_CLASS_NAME = 'rmc-result-span'; RationalModConverter.str2mod = [ ['998244353', 998244353], ['1000000007', 1000000007], ['10^{9}+7', 1000000007], ['10^9+7', 1000000007], ['109+7', 1000000007], ]; (() => { window.addEventListener('load', () => { new RationalModConverter(); }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址