【THUWC2017】在美妙的数学王国中畅游
题面
https://www.luogu.org/problem/P4546
题解
泰勒展开一般函数转多项式,$LCT$维护多项式。
#include<cmath> #include<stack> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ri register int #define N 120000 using namespace std; const double e=pow(2,1/log(2)); char typ[15]; int n,m,f[N],ch[N][2],ff[N],rev[N]; double ts[N][15],a[N],b[N]; stack<int> s; bool notroot(int x) { return ch[ff[x]][0]==x || ch[ff[x]][1]==x; } bool opt(int x) { return ch[ff[x]][1]==x; } void pushup(int x) { if (f[x]==1) { ts[x][0]=sin(a[x]*0.5+b[x]); ts[x][1]=cos(a[x]*0.5+b[x])*a[x]; for (ri i=2;i<15;i++) ts[x][i]=ts[x][i-2]*(-a[x]*a[x]); } else if (f[x]==2) { ts[x][0]=pow(e,0.5*a[x]+b[x]); for (ri i=1;i<15;i++) ts[x][i]=ts[x][i-1]*a[x]; } else if (f[x]==3) { ts[x][0]=0.5*a[x]+b[x]; ts[x][1]=a[x]; for (ri i=2;i<15;i++) ts[x][i]=0; } for (ri i=0;i<15;i++) ts[x][i]+=ts[ch[x][0]][i]+ts[ch[x][1]][i]; } void pushdown(int x) { if (!rev[x]) return; rev[x]=0; swap(ch[x][0],ch[x][1]); rev[ch[x][0]]^=1; rev[ch[x][1]]^=1; } void rotate(int x) { int y=ff[x],z=ff[y],s=opt(x),w=ch[x][1^s]; ff[x]=z; if (notroot(y)) ch[z][opt(y)]=x; ch[y][s]=w; ff[w]=y; ff[y]=x; ch[x][1^s]=y; pushup(y); pushup(x); } void splay(int x) { int tx=x; while (1) { s.push(tx); if (!notroot(tx)) break; tx=ff[tx]; } while (!s.empty()) pushdown(s.top()),s.pop(); while (notroot(x)) { if (!notroot(ff[x])) { rotate(x); } else { if (opt(x)==opt(ff[x])) rotate(ff[x]),rotate(x); else rotate(x),rotate(x); } } } void access(int x) { int y=0; while (x) { splay(x); ch[x][1]=y; pushup(x); y=x; x=ff[x]; } } void makeroot(int x) { access(x); splay(x); rev[x]^=1; } void split(int x,int y) { makeroot(x); access(y); splay(y); } void cut(int x,int y) { split(x,y); ff[x]=ch[y][0]=0; pushup(y); } void link(int x,int y) { makeroot(x); ff[x]=y; } int findroot(int x) { access(x); splay(x); while (ch[x][0]) x=ch[x][0]; return x; } int main() { scanf("%d %d %s",&n,&m,typ); for (ri i=1;i<=n;i++) scanf("%d %lf %lf",&f[i],&a[i],&b[i]); char ch[20]; for (ri i=1,u,v;i<=m;i++) { scanf("%s",ch); if (ch[0]=='a') { scanf("%d %d",&u,&v); u++; v++; link(u,v); } else if (ch[0]=='d') { scanf("%d %d",&u,&v); u++; v++; cut(u,v); } else if (ch[0]=='m') { scanf("%d",&u); u++; splay(u); scanf("%d %lf %lf",&f[u],&a[u],&b[u]); pushup(u); } else { double T; scanf("%d %d %lf",&u,&v,&T); u++; v++; if (findroot(u)!=findroot(v)) { puts("unreachable"); } else { double ans=0; split(u,v); double p1=1,p2=1; for (ri i=0;i<15;i++) ans+=ts[v][i]*p2/p1,p1*=(i+1),p2*=(T-0.5); printf("%.8e\n",ans); } } } return 0; }