神仙题。

第一场月赛的题目我到第二场月赛完了才写【由此可见我是真的菜

题目就是个大模拟加乘显然,幂的话需要将原函数、导函数的函数值用扩展欧拉定理展开 \(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();
}
}

随机推荐

  1. win10 ubuntu 子系统安装php

    apt-get install python-software-propertiesadd-apt-repository ppa:ondrej/phpapt-get updateapt-get ins ...

  2. vue中路由

    关于每次点击链接都要刷新页面的问题众所周知,开发单页应用就是因为那丝般顺滑的体验效果,如果每次点击都会刷新页面… 出现这个的原因是因为使用了window.location来跳转,只需要使用使用rout ...

  3. Jet --theory

    (FIG. 6. A caricature of turbulent jet and the entrainment., Jimmy, 2012) Ref: Jimmy Philip, Phys. F ...

  4. importdata-- matlab

    source file: test.dat *************************** Day1  Day2  Day3  Day4  Day5  Day6  Day795.01 76.2 ...

  5. codechef营养题 第三弹

    第三弾が始まる! codechef problems 第三弹 一.Motorbike Racing 题面 It's time for the annual exciting Motorbike Rac ...

  6. HDU 1085 多重背包转化为0-1背包问题

    题目大意: 给定一堆1,2,5价值的硬币,给定三个数表示3种价值硬币的数量,任意取,找到一个最小的数无法取到 总价值为M = v[i]*w[i](0<=i<3) 那么在最坏情况下M个数都能 ...

  7. codevs 1296 营业额统计 (splay 点操作)

    题目大意 每次加入一个值,并且询问之前加入的数中与该数相差最小的值. 答案输出所有相差值的总和. 解题分析 = = 参考程序 #include <bits/stdc++.h> using ...

  8. F - Piggy-Bank 完全背包问题

    Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. ...

  9. 最小生成树 E - QS Network

    Sunny Cup 2003 - Preliminary Round April 20th, 12:00 - 17:00 Problem E: QS Network In the planet w-5 ...

  10. zabbix全方位监控MySQL +cacti监控mysql

    http://www.linuxidc.com/Linux/2015-02/112690.htm http://john88wang.blog.51cto.com/2165294/1596272?ut ...