传送门:https://loj.ac/problem/2289
https://www.lydsy.com/JudgeOnline/problem.php?id=5020
s
o
l
u
t
i
o
n
solution
solution:
题目给了公式就比较容易了
x
0
=
0
x_0=0
x0=0的时候比较容易求解
s
i
n
(
a
x
+
b
)
=
s
i
n
(
b
)
+
a
c
o
s
(
b
)
1
!
x
−
a
2
s
i
n
(
b
)
2
!
x
2
−
a
3
c
o
s
(
b
)
3
!
x
3
+
a
4
s
i
n
(
b
)
4
!
x
4
.
.
.
sin(ax+b)=sin(b)+\frac{acos(b)}{1!}x-\frac{a^2sin(b)}{2!}x^2-\frac{a^3cos(b)}{3!}x^3+\frac{a^4sin(b)}{4!}x^4...
sin(ax+b)=sin(b)+1!acos(b)x−2!a2sin(b)x2−3!a3cos(b)x3+4!a4sin(b)x4...
e
a
x
+
b
=
e
b
+
a
e
b
1
x
+
a
2
e
b
2
!
x
2
+
a
3
e
b
3
!
x
3
+
.
.
.
.
.
e^{ax+b} =e^b+\frac{ae^b}{1}x+\frac{a^2e^b}{2!}x^2+\frac{a^3e^b}{3!}x^3+.....
eax+b=eb+1aebx+2!a2ebx2+3!a3ebx3+.....
a
x
+
b
=
a
x
+
b
ax+b=ax+b
ax+b=ax+b
可以发现
x
x
x只要展开
20
20
20项精度就够了(实测
11
11
11项即可
a
c
ac
ac)
然后我们只要用
L
C
T
LCT
LCT分别维护
x
i
x^i
xi的系数
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define rept(i,x) for(int i = linkk[x];i;i = e[i].n)
#define P pair<int,int>
#define Pil pair<int,ll>
#define Pli pair<ll,int>
#define Pll pair<ll,ll>
#define pb push_back
#define pc putchar
#define mp make_pair
#define file(k) memset(k,0,sizeof(k))
#define ll long long
#define ls ch[x][0]
#define rs ch[x][1]
int rd()
{
int sum = 0;char c = getchar();bool flag = true;
while(c < '0' || c > '9') {if(c == '-') flag = false;c = getchar();}
while(c >= '0' && c <= '9') sum = sum * 10 + c - 48,c = getchar();
if(flag) return sum;
else return -sum;
}
const int maxn = 101000;
struct tree
{
int ch[maxn][2],fa[maxn],rev[maxn];
double v[maxn][15],sigma[maxn][15];
int q[maxn],top;
void update(int x){rep(i,0,14) sigma[x][i] = sigma[ls][i] + sigma[rs][i] + v[x][i];}
void rorate(int x)
{
int y = fa[x],z = fa[y],k = ch[y][1] == x;
if(!isroot(y)) ch[z][ch[z][1] == y] = x;
fa[x]=z;fa[y]=x; ch[y][k] = ch[x][k^1];
ch[x][k^1] = y; fa[ch[y][k]] = y;
update(y);update(x);
}
bool isroot(int x){return ch[fa[x]][1] != x && ch[fa[x]][0] != x;}
void pushdown(int x){if(rev[x]){rev[ls] ^= 1;rev[rs] ^= 1;swap(ls,rs);rev[x] = 0;}}
void splay(int x)
{
int k = x;top = 0;
while(1)
{
q[++top] = k;
if(isroot(k)) break;
k = fa[k];
}
while(top) pushdown(q[top--]);
while(!isroot(x))
{
int y = fa[x],z = fa[y];
if(!isroot(y)) rorate((ch[y][1] == x)^(ch[z][1] == y)?y:x);
rorate(x);
}
}
void access(int x){for(int t=0;x;x = fa[t=x]) splay(x),ch[x][1] = t,update(x);}
void makeroot(int x){access(x);splay(x);rev[x] ^= 1;}
void link(int x,int y){makeroot(x);fa[x] = y;}
void split(int x,int y){makeroot(x);access(y);splay(y);}
void cut(int x,int y){
makeroot(x);access(y);splay(y);
fa[x] = ch[y][ch[y][1] == x] = 0;update(y);
}
int findroot(int x){access(x);splay(x);while(ls)x=ls;return x;}
}T;
int n,m;
ll fac[20];
char s[20];
void change(int op,int x,double a,double b)
{
if(op == 1)
{//
double pi=1,C = cos(b),S = sin(b);int f;
rep(i,0,14)
{
f = (i>>1&1)?-1:1;
T.v[x][i] = f*pi*(i&1?C:S)/fac[i];
pi *= a;
}
}
else
if(op == 2)
{
double e = exp(b),pi = 1;
rep(i,0,14)
{
T.v[x][i] = pi*e/fac[i];
pi *= a;
}
}
else
{
T.v[x][0] = b;T.v[x][1] = a;
rep(i,2,14) T.v[x][i] = 0;
}
}
void init()
{
fac[0] = 1;
rep(i,1,14) fac[i] = fac[i-1]*i;
n = rd();m = rd();scanf("%s",s+1);
rep(i,1,n)
{
int k = rd();double x,y;
scanf("%lf%lf",&x,&y);
change(k,i,x,y);
}
}
double query(int u,int v,double x)
{
T.makeroot(u);T.access(v);T.splay(v);
double ans = 0,tmp = 1;
rep(i,0,14)
ans += tmp*T.sigma[v][i],tmp *= x;
return ans;
}
int main()
{
init();
rep(i,1,m)
{
scanf("%s",s+1);
int x,y;
if(s[1] == 'a')
{
x = rd()+1,y = rd()+1;
T.link(x,y);
}
else
if(s[1] == 'd')
{
x = rd()+1,y = rd()+1;
T.cut(x,y);
}
else
if(s[1] == 'm')
{
int x = rd()+1,k = rd();
double a,b;
T.makeroot(x);
scanf("%lf%lf",&a,&b);
change(k,x,a,b);
T.update(x);
}
else
{
int x = rd()+1,y = rd()+1;double z;
scanf("%lf",&z);
if(T.findroot(x) != T.findroot(y)) printf("unreachable\n");
else printf("%.9lf\n",query(x,y,z));
}
}
return 0;
}