首先显然
e
x
e^x
ex和
s
i
n
sin
sin都不好维护整体
发现他给你了个提示
那么显然就是要用的了
那么就可以直接把
e
e
e和
s
i
n
sin
sin在
x
=
0
x=0
x=0处
展开展开个十几项
由于有除以阶乘所以后面的就小到可以忽略不计了
其中
e
a
x
+
b
=
∑
i
e
b
(
a
x
)
i
i
!
e^{ax+b}=\sum_{i}\frac{e^b(ax)^i}{i!}
eax+b=∑ii!eb(ax)i
s
i
n
(
a
x
+
b
)
=
∑
i
f
(
i
)
(
b
)
(
a
x
)
i
i
!
sin(ax+b)=\sum_{i} \frac{f^{(i)}(b)(ax)^i}{i!}
sin(ax+b)=∑ii!f(i)(b)(ax)i
s
i
n
(
x
)
′
=
c
o
s
(
x
)
sin(x)'=cos(x)
sin(x)′=cos(x)
c
o
s
(
x
)
′
=
−
s
i
n
(
x
)
cos(x)'=-sin(x)
cos(x)′=−sin(x)
然后维护即可
用数组维护多项式比用 v e c t o r vector vector快了一倍。。。
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re regitster
#define pb push_back
#define fi first
#define se second
#define pii pair<int,int>
#define ll long long
#define bg begin
#define gc getchar
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline void readstring(char *s){
int top=0;
char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
}
template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
#define poly vector<double>
cs int N=100005,Lim=16;
inline void Plus(double *a,double *b){
for(int i=0;i<Lim;i++)
a[i]+=b[i];
}
inline double F(double *a,double x){
double ret=0,mt=1;
for(int i=0;i<Lim;i++,mt*=x)ret+=a[i]*mt;
return ret;
}
double fac[Lim];
inline void init_fac(){
fac[0]=1;
for(int i=1;i<Lim;i++)fac[i]=fac[i-1]*i;
}
inline void getval(double *ret,int op,double f1,double f2){
double mt=1;
for(int i=0;i<Lim;i++)ret[i]=0;
if(op==1){
double c1=sin(f2),c2=cos(f2);
for(int i=0;i<Lim;i++,mt*=f1){
switch(i%4){
case 0:ret[i]=(c1*mt/fac[i]);break;
case 1:ret[i]=(c2*mt/fac[i]);break;
case 2:ret[i]=(-c1*mt/fac[i]);break;
case 3:ret[i]=(-c2*mt/fac[i]);break;
}
}
}
else if(op==2){
double c=exp(f2);
for(int i=0;i<Lim;i++,mt*=f1){
ret[i]=(c*mt/fac[i]);
}
}
else{
ret[0]=f2,ret[1]=f1;
}
}
namespace Lct{
double val[N][16],s[N][16];
int son[N][2],rev[N],fa[N];
#define lc(u) son[u][0]
#define rc(u) son[u][1]
inline void pushup(int u){
for(int i=0;i<Lim;i++)s[u][i]=val[u][i];
if(lc(u))Plus(s[u],s[lc(u)]);
if(rc(u))Plus(s[u],s[rc(u)]);
}
inline void pushrev(int u){
swap(lc(u),rc(u)),rev[u]^=1;
}
inline void pushdown(int u){
if(!rev[u])return;
if(lc(u))pushrev(lc(u));
if(rc(u))pushrev(rc(u));
rev[u]=0;
}
inline bool isrt(int u){
return !fa[u]||(lc(fa[u])!=u&&rc(fa[u])!=u);
}
inline bool isrc(int u){
return rc(fa[u])==u;
}
inline void init(int u,int op,double f1,double f2){
getval(val[u],op,f1,f2),pushup(u);
}
inline void rotate(int v){
int u=fa[v],z=fa[u];
int t=isrc(v);
if(!isrt(u))son[z][isrc(u)]=v;
fa[v]=z;
fa[son[v][t^1]]=u;
son[u][t]=son[v][t^1];
fa[u]=v,son[v][t^1]=u;
pushup(u),pushup(v);
}
int stk[N],top;
inline void splay(int u){
stk[top=1]=u;
for(int v=u;!isrt(v);v=fa[v])stk[++top]=fa[v];
for(int i=top;i;i--)pushdown(stk[i]);
while(!isrt(u)){
if(!isrt(fa[u]))
isrc(fa[u])==isrc(u)?rotate(fa[u]):rotate(u);
rotate(u);
}
}
inline void access(int u){
for(int v=0;u;v=u,u=fa[u]){
splay(u);
rc(u)=v;
pushup(u);
}
}
inline int findrt(int u){
access(u),splay(u);
while(pushdown(u),lc(u))u=lc(u);splay(u);
return u;
}
inline void makert(int u){
access(u),splay(u),pushrev(u);
}
inline void link(int u,int v){
makert(u),access(v),splay(v),fa[u]=v,pushup(v);
}
inline void cut(int u,int v){
makert(u),access(v),splay(v);
lc(v)=fa[u]=0,pushup(v);
}
inline void update(int u,int op,double f1,double f2){
access(u),splay(u),getval(val[u],op,f1,f2),pushup(u);
}
inline double query(int u,int v,double x){
makert(u),access(v),splay(v);
return F(s[v],x);
}
}
int n,m;
char s[N];
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
#endif
n=read(),m=read();
readstring(s);
init_fac();
double f1,f2;
for(int i=1;i<=n;i++){
int op=read();
scanf("%lf%lf",&f1,&f2);
Lct::init(i,op,f1,f2);
}
for(int i=1,u,v;i<=m;i++){
readstring(s);
u=read(),v=read();
switch(s[1]){
case 'a':Lct::link(u+1,v+1);break;
case 'd':Lct::cut(u+1,v+1);break;
case 't':{
scanf("%lf",&f1),u++,v++;
if(Lct::findrt(u)!=Lct::findrt(v)){puts("unreachable");}
else printf("%.10lf\n",Lct::query(u,v,f1));
break;
}
case 'm':{
scanf("%lf%lf",&f1,&f2);
Lct::update(u+1,v,f1,f2);
break;
}
}
}
}