[THUWC2017]在美妙的数学王国中畅游 LCT+泰勒展开+求导
Code:
#include<bits/stdc++.h>
using namespace std;
#define maxn 500000
#define M 17
#define setIO(s) freopen(s".in","r",stdin) //,freopen(s".out","w",stdout)
namespace tree{
#define ls ch[x][0]
#define rs ch[x][1]
#define lson ch[x][0]
#define rson ch[x][0]
int ch[maxn][2],f[maxn],op[maxn],rev[maxn];
int sta[maxn];
double s[maxn][30],a[maxn],b[maxn];
int get(int x){ return ch[f[x]][1]==x; }
int isrt(int x){ return !(ch[f[x]][0]==x||ch[f[x]][1]==x); }
void rever(int x){
if(!x) return;
rev[x]^=1;
swap(ch[x][0],ch[x][1]);
}
void pd(int x){
if(!rev[x]||!x) return;
if(rev[x]) rever(ch[x][0]),rever(ch[x][1]),rev[x]=0;
}
void up(int x){
for(int i=0;i<M;++i)s[x][i]=s[ch[x][0]][i]+s[ch[x][1]][i];
if(op[x]==1){
double val=1.00000,Sin=sin(b[x]),Cos=cos(b[x]);
for(int i=0;i<M;i+=4){
s[x][i]+=val*Sin,val*=a[x];
s[x][i+1]+=val*Cos,val*=a[x];
s[x][i+2]-=val*Sin,val*=a[x];
s[x][i+3]-=val*Cos,val*=a[x];
}
}
if(op[x]==2){
double EXP=exp(b[x]),val=1.000000;
for(int i=0;i<M;++i){
s[x][i]+=EXP*val,val*=a[x];
}
}
if(op[x]==3){
s[x][0]+=b[x],s[x][1]+=a[x];
}
}
void rotate(int x){
int old=f[x],oldf=f[old],which=get(x);
if(!isrt(old))ch[oldf][ch[oldf][1]==old]=x;
ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
ch[x][which^1]=old,f[old]=x,f[x]=oldf;
up(old),up(x);
}
void splay(int x){
int v=0,u=x;
sta[++v]=u;
while(!isrt(u)) sta[++v]=f[u],u=f[u];
while(v) pd(sta[v--]);
u=f[u];
for(int fa;(fa=f[x])!=u;rotate(x))
if(f[fa]!=u) rotate(get(fa)==get(x)?fa:x);
}
void Access(int x){
for(int y=0;x;y=x,x=f[x]) splay(x),ch[x][1]=y,up(x);
}
void makert(int x){
Access(x),splay(x),rever(x);
}
void split(int x,int y){
makert(x),Access(y),splay(y);
}
void del(int x,int y){
split(x,y); f[x]=ch[y][0]=0; up(y);
}
void link(int x,int y){
makert(x),f[x]=y;
}
int fd(int x){
Access(x);
splay(x);
while(ch[x][0]) x=ch[x][0];
splay(x); return x;
}
};
double jc[maxn];
void init(){
jc[0]=1.000;
for(int i=1;i<M;++i) jc[i]=jc[i-1]*i;
}
int main(){
//setIO("input");
init();
char str[20];
int n,m;
scanf("%d%d%s",&n,&m,str);
for(int i=1;i<=n;++i) scanf("%d%lf%lf",&tree::op[i],&tree::a[i],&tree::b[i]);
while(m--){
scanf("%s",str);
if(str[0]=='a') {
int x,y;
scanf("%d%d",&x,&y);
++x,++y;
tree::link(x,y);
}
if(str[0]=='d') {
int x,y;
scanf("%d%d",&x,&y);
++x,++y;
tree::del(x,y);
}
if(str[0]=='m'){
int x,y;
double w,k;
scanf("%d%d%lf%lf",&x,&y,&w,&k);
++x;
tree::Access(x),tree::splay(x);
tree::op[x]=y,tree::a[x]=w,tree::b[x]=k;
tree::up(x);
}
if(str[0]=='t'){
int u,v;
double w;
scanf("%d%d%lf",&u,&v,&w);
++u,++v;
if(tree::fd(u)!=tree::fd(v)){
printf("unreachable\n");
}else{
tree::split(u,v);
double ans=0.0,val=1.00000;
for(int i=0;i<M;++i){
ans+=(double)tree::s[v][i]*val/jc[i];
val*=w;
}
printf("%.8e\n",ans);
}
}
}
return 0;
}