首先发现有连边和删边的操作,所以我们肯定要用\(LCT\)来进行维护。

接下来考虑如何进行\(LCT\)上的信息合并。

\(f=1\),则函数为\(f(x)=sin(ax+b)\)

\(f=2\),则函数为\(f(x)=e^{ax+b}\)

\(f=3\),则函数为\(f(x)=ax+b\)

这道题中的信息为这三个函数,因为\(sin(ax+b)\)和\(e^{ax+b}\)不好处理,所以用泰勒展开都其处理为多项式的形式,再进行多项式的合并即可。

泰勒公式:

\[f(x)=\sum_{i=0}^{n} \frac{f^{(i)}(x_0)\times(x-x_0)^i}{i!}
\]

我们让\(x_0=0\),得:

\[f(x)=\sum_{i=0}^{n} \frac{f^{(i)}(0)}{i!}x^i
\]

根据求导的知识,得:

\[(\sin x)'=\cos x
\]

\[(\cos x)'=-\sin x
\]

\[(-\sin x)'=-\cos x
\]

\[(-\cos x)'=\sin x
\]

\[(e^x)'=e^x
\]

同时再应用链式法则。

对\(sin(ax+b)\)进行泰勒展开得:

\[sin(ax+b)=\sum_{i=0}^{n} \frac{f^{(i)}(0)}{i!}x^i
\]

其中,\(f^{(i)}(0)\)为:

\[f^{(i)}(0)=\begin{cases}\sin(b)a^i\ (i\mod4=0)\\\cos(b)a^i\ (i\mod4=1)\\-\sin(b)a^i\ (i\mod4=2)\\-\cos(b)a^i\ (i\mod4=3)\end{cases}
\]

对\(e^{ax+b}\)进行泰勒展开得:

\[e^{ax+b}=\sum_{i=0}^{n} \frac{f^{(i)}(0)}{i!}x^i=\sum_{i=0}^{n} \frac{a^ie^b}{i!}x^i
\]

解决了信息合并后,修改查询什么的都是\(LCT\)的基本操作了,然后这道题就做完了。

实现细节看代码吧。

\(code:\)

#include<bits/stdc++.h>
#define maxn 100010
#define maxm 20
using namespace std;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
int n,m;
char type[10];
int fa[maxn],ch[maxn][2],rev[maxn],f[maxn];
double fac[maxm],sum[maxn][maxm],a[maxn],b[maxn];
bool check(int x)
{
return ch[fa[x]][1]==x;
}
void pushr(int x)
{
rev[x]^=1;swap(ch[x][0],ch[x][1]);
}
void pushup(int x)
{
for(int i=0;i<=15;++i)
sum[x][i]=sum[ch[x][0]][i]+sum[ch[x][1]][i];
if(f[x]==1)
{
double val=1,s=sin(b[x]),c=cos(b[x]);
for(int i=0;i<=15;i+=4)
{
sum[x][i]+=s*val,val*=a[x];
sum[x][i+1]+=c*val,val*=a[x];
sum[x][i+2]-=s*val,val*=a[x];
sum[x][i+3]-=c*val,val*=a[x];
}
}
if(f[x]==2)
{
double val=exp(b[x]);
for(int i=0;i<=15;++i) sum[x][i]+=val,val*=a[x];
}
if(f[x]==3) sum[x][1]+=a[x],sum[x][0]+=b[x];
}
void pushdown(int x)
{
if(!rev[x]) return;
pushr(ch[x][0]),pushr(ch[x][1]);
rev[x]=0;
}
bool notroot(int x)
{
return ch[fa[x]][0]==x||ch[fa[x]][1]==x;
}
void rotate(int x)
{
int y=fa[x],z=fa[y],k=check(x),w=ch[x][k^1];
if(notroot(y)) ch[z][check(y)]=x;
fa[x]=z;
ch[y][k]=w;
if(w) fa[w]=y;
ch[x][k^1]=y;
fa[y]=x;
pushup(y);
}
void all(int x)
{
if(notroot(x)) all(fa[x]);
pushdown(x);
}
void splay(int x)
{
all(x);
for(int y;notroot(x);rotate(x))
if(notroot(y=fa[x]))
rotate(check(x)^check(y)?x:y);
pushup(x);
}
void access(int x)
{
for(int y=0;x;y=x,x=fa[x])
splay(x),ch[x][1]=y,pushup(x);
}
void makeroot(int x)
{
access(x),splay(x),pushr(x);
}
void split(int x,int y)
{
makeroot(x),access(y),splay(y);
}
int findroot(int x)
{
access(x),splay(x);
while(ch[x][0]) x=ch[x][0];
splay(x);
return x;
}
void link(int x,int y)
{
makeroot(x),fa[x]=y;
}
void cut(int x,int y)
{
split(x,y),fa[x]=ch[y][0]=0;
}
void modify(int x,int nf,double na,double nb)
{
makeroot(x);
f[x]=nf,a[x]=na,b[x]=nb;
}
double query(int x,int y,double q)
{
double ans=0,now=1;
split(x,y);
for(int i=0;i<=15;++i)
ans+=sum[y][i]*now/fac[i],now*=q;
return ans;
}
void init()
{
fac[0]=1;
for(int i=1;i<=18;++i) fac[i]=fac[i-1]*i;
}
int main()
{
init();
read(n),read(m);
scanf("%s",type);
for(int i=1;i<=n;++i)
read(f[i]),scanf("%lf%lf",&a[i],&b[i]);
while(m--)
{
int x,y,nf;
double na,nb,q;
scanf("%s",type);
if(type[0]=='a')
read(x),read(y),link(x+1,y+1);
if(type[0]=='d')
read(x),read(y),cut(x+1,y+1);
if(type[0]=='m')
{
read(x),read(nf),x++;
scanf("%lf%lf",&na,&nb);
modify(x,nf,na,nb);
}
if(type[0]=='t')
{
read(x),read(y),x++,y++;
scanf("%lf",&q);
if(findroot(x)!=findroot(y))
{
puts("unreachable");
continue;
}
printf("%.10lf\n",query(x,y,q));
}
}
return 0;
}

最新文章

  1. 利用闭包解决for循环里onclick事件不能捕捉实时i值问题
  2. NIOS II 中直接调用Modelsim仿真
  3. [BZOJ1528][POI2005]sam-Toy Cars(贪心)
  4. ubifs核心功能 -- 垃圾回收
  5. delphi TToolBar
  6. 使用CPU的AVX指令
  7. Expression Language
  8. pthread_wrap.h
  9. U+00A0 (Non-breaking space)无法被正确压缩
  10. java字符串比较及小数浮点型的使用
  11. 性能测试培训:定位jvm耗时函数
  12. MyBatis_Generator插件的安装以及简单使用
  13. 傻瓜式安装nginx以及负载均衡配置
  14. Python练习--普通函数与递归函数求阶乘
  15. IOPLL动态重配
  16. Asp.net Mvc之Action如何传多个参数
  17. 学习Spring Boot:(十七)Spring Boot 中使用 Redis
  18. PAT 1042 Shuffling Machine[难]
  19. 1.struts 防止表单重复提交 2. 拦截器
  20. Xcode的快捷键及代码格式化

热门文章

  1. 为什么说String是线程安全的
  2. 黎活明8天快速掌握android视频教程--16_采用SharedPreferences保存用户偏好设置参数
  3. @Inherited 注解的作用
  4. HashMap的基本使用
  5. java使字符串的数字加一
  6. vim常用指令参考
  7. HTTPS 和 SSL/TLS 协议:密钥交换(密钥协商)算法及其原理
  8. MongoDB安装和入门
  9. Kail安装VMtools
  10. 一篇文章教会你如何将DOM转换为virtual DOM