[THUWC2017]在美妙的数学王国中畅游

[THUWC2017]在美妙的数学王国中畅游

第一发95T了一个点

卡常数就过了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
typedef double ld;
const int maxn = 100100;
int n,m;
const ld pi = acosl(-1);
const int N = 13;
struct poly{
    ld a[N];
    inline ld operator () (const ld&b)const{
        ld ret=0;
        for(int i=N-1;~i;--i)ret=ret*b+a[i];
        return ret;
    }
    inline ld operator [] (const int&b)const {return a[b];}
    inline ld&operator [] (const int&b){return a[b];}
    inline poly&operator += (const poly & b){
        a[0]+=b[0],a[1]+=b[1],a[2]+=b[2],a[3]+=b[3],a[4]+=b[4];
        a[5]+=b[5],a[6]+=b[6],a[7]+=b[7],a[8]+=b[8],a[9]+=b[9];
        a[10]+=b[10],a[11]+=b[11],a[12]+=b[12];
        return *this;
    }
    inline void cls(){memset(a,0,sizeof a);}
    inline poly(){}
};
inline ld getder(int n,ld v){
    n &= 3;
    if(n == 0)return sinl(v);
    if(n == 1)return cosl(v);
    if(n == 2)return -sinl(v);
    return -cosl(v);
}
inline poly exp(ld a,ld b){
    ld ml=1;
    const ld x0=b,expx0=expl(x0);
    poly ret;
    for(int i=0;i<N;++i,ml/=i)ret.a[i]=expx0*ml,ml*=a;
    return ret;
}
inline poly sin(ld a,ld b){
    const ld x0=b;
    ld ml=1;
    poly ret;
    for(int i=0;i<N;++i,ml/=i)ret.a[i]=getder(i,x0)*ml,ml*=a;
    return ret;
}
inline poly func(ld a,ld b){
    poly ret;ret.cls();ret.a[0]=b,ret.a[1]=a;
    return ret;
}
poly val[maxn],sum[maxn];
int son[maxn][2],fa[maxn],tag[maxn];
inline int get(int x,int p=1){return son[fa[x]][p]==x;}
inline int is_root(int x){return !(get(x)||get(x,0));}
inline void up(int x){((sum[x]=val[x])+=sum[son[x][0]])+=sum[son[x][1]];}
inline void rotate(int x){
    int y=fa[x],z=fa[y],b=get(x);
    if(!is_root(y))son[z][get(y)]=x;
    son[y][b]=son[x][!b],son[x][!b]=y;
    fa[son[y][b]]=y,fa[y]=x,fa[x]=z;
    up(y);
}
inline void down(int x){
    if(tag[x]){
        tag[son[x][0]]^=1,tag[son[x][1]]^=1;
        std::swap(son[x][0],son[x][1]),tag[x]=0;
    }
}
int st[maxn],top;
inline void splay(int x){
    st[top=1]=x;
    for(int y=x;!is_root(y);st[++top]=y=fa[y]);
    for(;top;--top)down(st[top]);
    for(;!is_root(x);rotate(x))
        if(!is_root(fa[x]))rotate(get(x)^get(fa[x])?x:fa[x]);
    up(x);
}
inline void access(int x){for(int t=0;x;son[x][1]=t,t=x,x=fa[x])splay(x);}
inline void make_root(int x){access(x),splay(x),tag[x]^=1;}
inline void split(int x,int y){make_root(x),access(y),splay(y);}
inline int con(int x,int y){
    split(x,y);
    int now=x;while(!is_root(now))now=fa[now];
    return now==y;
}
inline void link(int x,int y){make_root(x),fa[x]=y;}
inline void cut(int x,int y){split(x,y),fa[x]=son[y][0]=0,up(y);}
int main(){
    std::ios::sync_with_stdio(false),std::cin.tie(0);
    char buf[20];
    std::cin >> n >> m >> buf;
    for(int i=1;i<=n;++i){
        ld f,a,b;
        std::cin >> f >> a >> b;
        if(f==1)sum[i]=val[i]=sin(a,b);
        if(f==2)sum[i]=val[i]=exp(a,b);
        if(f==3)sum[i]=val[i]=func(a,b);
    }
    for(int i=1;i<=m;++i){
        std::cin >> buf;
        int u,v,c;
        ld f,a,b,x;
        if(*buf=='a') std::cin >> u >> v,link(u+1,v+1);
        if(*buf=='d') std::cin >> u >> v,cut(u+1,v+1);
        if(*buf=='m'){
            std::cin >> c >> f >> a >> b;
            make_root(++c);
            if(f==1)sum[c]=val[c]=sin(a,b);
            if(f==2)sum[c]=val[c]=exp(a,b);
            if(f==3)sum[c]=val[c]=func(a,b);
            up(c);
        }
        if(*buf=='t'){
            std::cin >> u >> v >> x;
            if(con(++u,++v)) printf("%.8e
",sum[v](x));
            else puts("unreachable");
        }
    }
}