Orz w_yqts
lct+泰勒展开
#include <bits/stdc++.h>
using namespace std;
#define db double
#define N 666666
#define m 20
struct lct
{
int c[2],f,rev;
db s[m],v[m];
}tr[N];
db C[m][m];
int top,stk[N];
inline int isroot(int x)
{
return (!tr[x].f) || (tr[tr[x].f].c[0]!=x && tr[tr[x].f].c[1]!=x);
}
inline void update(int x)
{
int l=tr[x].c[0],r=tr[x].c[1];
for (int i=0;i<m;++i) tr[x].s[i]=tr[x].v[i]+tr[l].s[i]+tr[r].s[i];
}
inline void pushdown(int x)
{
if (!tr[x].rev) return;
int l=tr[x].c[0],r=tr[x].c[1];
swap(tr[x].c[0],tr[x].c[1]);
tr[l].rev^=1;tr[r].rev^=1;
tr[x].rev=0;
}
inline void rotate(int x)
{
int y=tr[x].f,z=tr[y].f,l,r;
l=tr[y].c[1]==x,r=l^1;
if (!isroot(y)) tr[z].c[tr[z].c[1]==y]=x;
tr[tr[x].c[r]].f=y;tr[y].f=x;tr[x].f=z;
tr[y].c[l]=tr[x].c[r];tr[x].c[r]=y;
update(y);
}
inline void splay(int x)
{
int t=x;
while (!isroot(t)) stk[++top]=t,t=tr[t].f;
stk[++top]=t;
while (top) pushdown(stk[top--]);
while (!isroot(x))
{
int y=tr[x].f,z=tr[y].f;
if (!isroot(y))
{
if (tr[y].c[0]==x ^ tr[z].c[0]==y) rotate(x);
else rotate(y);
}
rotate(x);
}
update(x);
}
inline void access(int x)
{
int t=0,tt=x;
while (x)
{
splay(x);
tr[x].c[1]=t;
update(x);
t=x;x=tr[x].f;
}
splay(tt);
}
inline void makeroot(int x)
{
access(x);tr[x].rev^=1;
}
int find(int x)
{
while (tr[x].f) x=tr[x].f;
return x;
}
inline void link(int x,int y)
{
makeroot(x);
tr[x].f=y;
}
inline void cut(int x,int y)
{
makeroot(x);
access(y);
tr[y].c[0]=tr[x].f=0;
update(y);
}
db ta[m],tb[m],fx[m],jc[m];
inline void modify(int x,int f,db fa,db fb)
{
access(x);
ta[0]=1.0;tb[0]=1.0;
for (int i=1;i<m;++i) ta[i]=ta[i-1]*fa,tb[i]=tb[i-1]*fb;
for (int i=0;i<m;++i) tr[x].v[i]=0.0;
if (f==3) {tr[x].v[0]=fb;tr[x].v[1]=fa;return;}
for (int i=0;i<m;++i)
{
for (int j=0;j<=i;++j)
{
db t=ta[j]*tb[i-j]*C[i][j]/jc[i];
if (f==1)
{
if (i%2==0) t=0.0;
else if (i%4==3) t=-t;
}
tr[x].v[j]+=t;
}
}
}
int n;
inline void solve()
{
char type[100];
int x,y,f;
db fa,fb,iq;
scanf("%s",type);
if (type[0]=='a')
{
scanf("%d%d",&x,&y);
++x,++y;
link(x,y);
return;
}
if (type[0]=='d')
{
scanf("%d%d",&x,&y);
++x,++y;
cut(x,y);
return;
}
if (type[0]=='m')
{
scanf("%d%d%lf%lf",&x,&f,&fa,&fb);
++x;
modify(x,f,fa,fb);
update(x);
return;
}
db ans=0.0;
scanf("%d%d%lf",&x,&y,&iq);
++x,++y;
if (find(x) != find(y)) {puts("unreachable");return;}
makeroot(y);access(x);
fx[0]=1.0;
for (int i=1;i<m;++i) fx[i]=fx[i-1]*iq;
for (int i=0;i<m;++i) ans+=fx[i]*tr[x].s[i];
printf("%.8le\n",ans);
//for (int i=0;i<m;++i) printf("%.2lf ",tr[x].s[i]);cout<<endl;
}
int main()
{
int Q;
char stype[100];
jc[0]=1.0;
for (int i=1;i<m;++i) jc[i]=jc[i-1]*i;
C[0][0]=1.0;
C[1][0]=C[1][1]=1.0;
for (int i=2;i<m;++i)
{
C[i][0]=C[i][i]=1.0;
for (int j=1;j<i;++j) C[i][j]=C[i-1][j-1]+C[i-1][j];
}
cin>>n>>Q;
scanf("%s",stype);
for (int i=1;i<=n;++i)
{
int f;
db fa,fb;
scanf("%d%lf%lf",&f,&fa,&fb);
modify(i,f,fa,fb);
}
while (Q--) solve();
}