题目里给的提示很明显了,我们要用泰勒公式去做这些函数,因为泰勒公式收敛的很快,只用保留个前十几项精度就够了。
那么就是求那三种函数的(i<=15)次导在(x0=0)处的值。
(sin(ax+b)^{(k)}=a^ksin(ax+b+(pi/2)*k))
((e^{ax+b})^{(k)}=a^ke^{ax+b})
((ax+b)^{(0)}=ax+b)
((ax+b)^{(1)}=a)
((ax+b)^{(k>1)}=0)
有了公式之后就可以算出,剩下的就是lct维护路径和的事。
Code:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i < _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("
")
using namespace std;
#define db double
const db pi = acos(-1);
db sin_x0(db a, db b, int k) {
return pow(a, k) * sin(b + (pi / 2) * k);
}
db exp_x0(db a, db b, int k) {
return exp(b) * pow(a, k);
}
db k_x0(db a, db b, int k) {
if(k == 0) return b;
if(k == 1) return a;
return 0;
}
const int w = 15;
db fac[w + 1];
const int N = 1e5 + 5;
char str[10];
int n, m;
int x, y; db u, v;
db f[N][w + 1], g[N][w + 1];
void cz(int i, int x, db y, db z) {
fo(j, 0, w) {
if(x == 1) g[i][j] = sin_x0(y, z, j);
if(x == 2) g[i][j] = exp_x0(y, z, j);
if(x == 3) g[i][j] = k_x0(y, z, j);
}
}
#define x0 t[x][0]
#define x1 t[x][1]
int fa[N], t[N][2], siz[N], rev[N], dd[N], pf[N];
void fan(int x) { if(x) swap(x0, x1), rev[x] ^= 1;}
void down(int x) { if(rev[x]) fan(x0), fan(x1), rev[x] = 0;}
void xc(int x) {
for(; x; x = fa[x]) dd[++ dd[0]] = x;
while(dd[0]) down(dd[dd[0] --]);
}
void upd(int x) {
if(x) {
siz[x] = siz[x0] + siz[x1];
fo(j, 0, w) f[x][j] = (f[x0][j] + f[x1][j] + g[x][j]);
}
}
int lr(int x) { return t[fa[x]][1] == x;}
void ro(int x) {
int y = fa[x], k = lr(x);
t[y][k] = t[x][!k]; if(t[x][!k]) fa[t[x][!k]] = y;
fa[x] = fa[y]; if(fa[y]) t[fa[y]][lr(y)] = x;
fa[y] = x, t[x][!k] = y, pf[x] = pf[y];
upd(y); upd(x);
}
void sp(int x, int y) {
xc(x);
for(; fa[x] != y; ro(x)) if(fa[fa[x]] != y)
ro(lr(x) == lr(fa[x]) ? fa[x] : x);
}
void ac(int x) {
int xx = x;
for(int y = 0; x; ) {
sp(x, 0), fa[x1] = 0, pf[x1] = x;
fa[y] = x, x1 = y, pf[y] = 0;
upd(x), y = x, x = pf[x];
}
sp(xx, 0);
}
void mr(int x) {
ac(x); fan(x);
}
void link(int x, int y) {
mr(x); mr(y);
pf[x] = y;
ac(x);
}
void cut(int x, int y) {
mr(x); ac(y);
t[y][0] = fa[x] = pf[x] = 0;
upd(y);
}
int fl(int x) {
down(x);
return x0 ? fl(x0) : x;
}
int pd(int x, int y) {
mr(x); ac(y);
int z = fl(y);
sp(z, 0);
return x == z;
}
int main() {
fac[0] = 1; fo(i, 1, w) fac[i] = fac[i - 1] * i;
scanf("%d %d", &n, &m);
scanf("%s", str);
fo(i, 1, n) {
scanf("%d %lf %lf", &x, &u, &v);
cz(i, x, u, v); upd(i);
}
fo(ii, 1, m) {
scanf("%s", str);
if(str[0] == 'a') {
scanf("%d %d", &x, &y);
x ++; y ++;
link(x, y);
} else
if(str[0] == 'd') {
scanf("%d %d", &x, &y);
x ++; y ++;
cut(x, y);
} else
if(str[0] == 'm') {
scanf("%d %d %lf %lf", &x, &y, &u, &v);
x ++;
mr(x); cz(x, y, u, v); upd(x);
} else
if(str[0] == 't') {
scanf("%d %d %lf", &x, &y, &u);
x ++, y ++;
if(!pd(x, y)) {
pp("unreachable
");
continue;
}
mr(x); ac(y);
db s = 0, mi = 1;
fo(j, 0, w) {
s += f[y][j] / fac[j] * mi;
mi = mi * u;
}
pp("%.8lf
", s);
}
}
}