[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"); } } }