$P5240 Derivation$
神仙题。
第一场月赛的题目我到第二场月赛完了才写【由此可见我是真的菜
题目就是个大模拟加乘显然,幂的话需要将原函数、导函数的函数值用扩展欧拉定理展开 \(log\) 层。时间复杂度 \(O(T |S| \log^2p)\)
因为求导时要对指数减一,你可能会用加 (模数-1) 来实现,并且如果你的扩展欧拉定理写法是小于模数时是正常值,超过模数时用真实值 + 模数代替,就会导致错误,因为正常的快速幂中 \(0^0=1\)
但 \(0^P=0\) \((P≠0)\)
以下不是本人写的程序 是验题人写的
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define MAXN 10005
#define eps 1e-12
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MOD = 998244353;
char s[MAXN],que[MAXN];
int val[2],tot,phi[MAXN];
vector<pii > sta[2];
bool f[2][MAXN][2];
int eu(int x) {
int t = x;
for(int i = 2 ; i <= x / i ; ++i) {
if(x % i == 0) {
t = t / i * (i - 1);
while(x % i == 0) x /= i;
}
}
if(x > 1) t = t / x * (x - 1);
return t;
}
int fpow(int x,int c,int mod,bool &on) {
int64 res = 1,t = x;
if(c == 0) {on = 0;return 1;}
if(x == 1 || x == 0) return x;
while(c && !on) {
res = res * x;--c;
if(res >= MOD) {res %= mod;on = 1;break;}
}
while(c) {
if(c & 1) res = res * t % mod;
t = t * t % mod;
c >>= 1;
}
return res;
}
void Solve() {
scanf("%s",s + 2);
read(val[0]);read(val[1]);
s[1] = '(';
int L = strlen(s + 1);
s[L + 1] = ')';++L;
sta[0].clear();sta[1].clear();
tot = 0;
int lev = 0;
for(int i = 1 ; i <= L ; ++i) {
if(s[i] >= '0' && s[i] <= '9') {
if(s[i - 1] < '0' || s[i - 1] > '9') {
for(int k = 0 ; k <= 1 ; ++k) {
int v = s[i] - '0';
sta[k].pb(mp(v,(lev == 0 ? 0 : v)));
f[k][sta[k].size() - 1][0] = 0;
f[k][sta[k].size() - 1][1] = 0;
}
}
else {
for(int k = 0 ; k <= 1 ; ++k) {
auto t = sta[k].back();
int64 a = 1LL * t.fi * 10 + s[i] - '0';
int64 b = 1LL * t.se * 10 + s[i] - '0';
if(a >= MOD) {
f[k][sta[k].size() - 1][0] = 1;
a %= phi[lev];
}
if(b >= MOD) {
f[k][sta[k].size() - 1][1] = 1;
b %= phi[max(lev - 1,0)];
}
if(lev == 0) b = 0;
t = mp(a,b);
sta[k].pop_back();sta[k].push_back(t);
}
}
}
else if(s[i] == ')') {
if(!tot) break;
if(que[tot] == '^') --lev;
for(int k = 0 ; k <= 1 ; ++k) {
int si = sta[k].size() - 1;
auto t0 = sta[k][si - 1],t1 = sta[k][si];
sta[k].pop_back();sta[k].pop_back();
if(que[tot] == '^') {
if(f[k][si][0]) t1.fi += phi[lev + 1];
if(f[k][si][1]) t1.se += phi[lev];
if(lev) {
int a = fpow(t0.fi,t1.fi,phi[lev],f[k][si - 1][0]);
int b = fpow(t0.se,t1.se,phi[lev - 1],f[k][si - 1][1]);
sta[k].pb(mp(a,b));
}
else {
int a = fpow(t0.fi,t1.fi,MOD,f[k][si - 1][0]);
int b = 1LL * t1.se * t0.se % MOD;
if(t0.fi != 0)
b = 1LL * b * fpow(t0.fi,(1LL * t1.fi + (MOD - 2)) % (MOD - 1),MOD,f[k][si - 1][1]) % MOD;
else {
if(f[k][si][0]) b = 0;
else if(t1.fi - 1) b = 0;
}
sta[k].pb(mp(a,b));
}
}
else if(que[tot] == '+') {
f[k][si - 1][0] |= f[k][si][0];
f[k][si - 1][1] |= f[k][si][1];
t0.fi = t0.fi + t1.fi;
t0.se = t0.se + t1.se;
if(t0.fi >= MOD) {t0.fi %= phi[lev];f[k][si - 1][0] |= 1;}
if(t0.se >= MOD) {t0.se %= phi[max(0,lev - 1)];f[k][si - 1][1] |= 1;}
sta[k].pb(t0);
}
else if(que[tot] == '*') {
if(lev == 0) {
int64 a = 1LL * t0.fi * t1.fi % MOD;
int64 b = (1LL * t0.fi * t1.se % MOD + 1LL * t1.fi * t0.se % MOD) % MOD;
sta[k].pb(mp((int)a,(int)b));
}
else {
if((!f[k][si][0] && t1.fi == 0) || (!f[k][si - 1][0] && t0.fi == 0)) f[k][si - 1][0] = 0;
else f[k][si - 1][0] |= f[k][si][0];
if((!f[k][si][1] && t1.fi == 0) || (!f[k][si - 1][1] && t0.fi == 0)) f[k][si - 1][1] = 0;
else f[k][si - 1][1] |= f[k][si][1];
int64 a = 1LL * t0.fi * t1.fi;
int64 b = 1LL * t0.se * t1.se;
if(a >= MOD) {a %= phi[lev];f[k][si - 1][0] |= 1;}
if(b >= MOD) {b %= phi[lev - 1];f[k][si - 1][1] |= 1;}
sta[k].pb(mp((int)a,(int)b));
}
}
}
--tot;
}
else if(s[i] == 'x') {
sta[0].pb(mp(val[0],1));
sta[1].pb(mp(val[1],1));
}
else {
if(s[i] != '(') que[++tot] = s[i];
if(s[i] == '^') ++lev;
}
}
out(sta[0][0].se);space;out(sta[1][0].se);enter;
}
int main() {
#ifdef ivorysi
freopen("f2.in","r",stdin);
#endif
int T;
read(T);
phi[0] = MOD;
for(int i = 1 ; i <= 10000 ; ++i) {
phi[i] = eu(phi[i - 1]);
}
for(int i = 1 ; i <= T ; ++i) {
Solve();
}
}
随机推荐
- 马拉车,O(n)求回文串
马拉车,O(n)求回文串 对整个马拉车算法步骤做个总结: 第一步:将每个原字母用两个特殊字符包围如: aaa --> #a#a#a# abab -->#a#b#a#b 同时可以由这个翻倍的 ...
- Spring security 5 Authorize Configuration
1. Spring Security 核心请求,认证配置类 WebSecurityConfigurerAdapter protected void configure(HttpSecurity htt ...
- Shiro_认证思路分析
[认证] 也就是登录. 1.获取当前的subject,调用SecurityUtils.getSubject() 2.测试当前的用户是否已经被认证,即是否登录.调用subject的isAuthentic ...
- 【Codeforces 992B】Nastya Studies Informatics
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 因为gcd(a,b)=x 所以设a = nx b = mx 又有ab/gcd(a,b)=lcm(a,b)=y 则nmx = y 即n(m*x) ...
- mongo实践-透过js shell操作mongo
mongo实践-通过js shell操作mongo 保存命令: j={name:"wangjingjing",age:15} db.user.save(j); 查询命令: var ...
- ACM数论常用知识完全解读
此版本纯属扯淡....... 一个一个来起.
- poj 2114 树的分治 可作模板
/* 啊啊啊啊啊啊啊本题证明一个问题,在实际应用中sort比qsort块 还有memset这类初始化能不加尽量别加,很浪费时间 原来的程序把qsort该成sort,去掉一个无用memset就a了时间不 ...
- vue.js编程式路由导航 --- 由浅入深
编程式路由导航 实例中定义一个方法,这个方法绑定在标签上 然后就设置路由跳转 语法 this.$router.history.push('要跳转路由的地址') <!DOCTYPE html> ...
- java多线程编程核心技术(三)--线程间通信
1.等待/通知机制 1.wait()方法:使当前执行代码的线程进行等待.wait()方法是Object类的方法,该方法将当前线程放入“预执行队列”中,并在wait()所处的代码行处停止执行.只到被唤起 ...
- Win32编程API 基础篇 -- 3.消息处理 根据英文教程翻译
消息处理 例子:窗口点击 好的,现在我们已经得到一个窗口了,但我们什么也做不了除了DefWindowProc()允许窗口大小被调整,最大最小化等...这不是很激动人心啊 在接下来的一小节中我将向你展示 ...