首先发现有连边和删边的操作,所以我们肯定要用\(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;
}

题解 洛谷 P4546 【[THUWC2017]在美妙的数学王国中畅游】的更多相关文章

  1. 洛谷P4546 [THUWC2017]在美妙的数学王国中畅游 [LCT,泰勒展开]

    传送门 毒瘤出题人卡精度-- 思路 看到森林里加边删边,容易想到LCT. 然而LCT上似乎很难实现往一条链里代一个数进去求和,怎么办呢? 善良的出题人在下方给了提示:把奇怪的函数泰勒展开搞成多项式,就 ...

  2. 并不对劲的bzoj5020:loj2289:p4546:[THUWC2017]在美妙的数学王国中畅游

    题目大意 有一个n(\(n\leq 10^5\))个点的森林,每个点\(u\)上有个函数\(f_u(x)\),是形如\(ax+b\)或\(e^{ax+b}\)或\(sin(ax+b)\)的函数,保证当 ...

  3. Luogu P4546 [THUWC2017]在美妙的数学王国中畅游

    题意 题意奇奇怪怪,这里就不写了. \(\texttt{Data Range:}1\leq n\leq 10^5,1\leq m\leq 2\times 10^5\) 题解 为什么你们都是卡在数学方面 ...

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

    如果只有第3个操作,那么这就是个sd题,随便lct搞搞就过去了 然后就是一个神仙东西 taylor公式 我不会,看gsy博客https://www.cnblogs.com/zhoushuyu/p/81 ...

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

    [THUWC2017]在美妙的数学王国中畅游 e和sin信息不能直接合并 泰勒展开,大于21次太小,认为是0,保留前21次多项式即可 然后就把e,sin ,kx+b都变成多项式了,pushup合并 上 ...

  6. [BZOJ5020][THUWC2017]在美妙的数学王国中畅游(LCT)

    5020: [THUWC 2017]在美妙的数学王国中畅游 Time Limit: 80 Sec  Memory Limit: 512 MBSec  Special JudgeSubmit: 323  ...

  7. Luogu4546 THUWC2017 在美妙的数学王国中畅游 LCT、泰勒展开

    传送门 题意:反正就是一堆操作 LCT总是和玄学东西放在一起我们不妨令$x_0=0.5$(其实取什么都是一样的,但是最好取在$[0,1]$的范围内),将其代入给出的式子,我们得到的$f(x)$的式子就 ...

  8. BZOJ5020 THUWC2017在美妙的数学王国中畅游(LCT)

    明摆着的LCT,问题在于如何维护答案.首先注意到给出的泰勒展开式,并且所给函数求导非常方便,肯定要用上这玩意.容易想到展开好多次达到精度要求后忽略余项.因为x∈[0,1]而精度又与|x-x0|有关,当 ...

  9. [THUWC2017]在美妙的数学王国中畅游 LCT+泰勒展开+求导

    p.s. 复合函数求导时千万不能先带值,再求导. 一定要先将符合函数按照求导的规则展开,再带值. 设 $f(x)=g(h(x))$,则对 $f(x)$ 求导: $f'(x)=h'(x)g'(h(x)) ...

随机推荐

  1. 有return的情况下try_catch_finally的执行顺序

    java异常处理之try_catch_finally 看下面的一个列子: public class TestException { int goabl=1; public TestException( ...

  2. 入门大数据---通过Flume、Sqoop分析日志

    一.Flume安装 参考:Flume 简介及基本使用 二.Sqoop安装 参考:Sqoop简介与安装 三.Flume和Sqoop结合使用案例 日志分析系统整体架构图: 3.1配置nginx环境 请参考 ...

  3. 前端基础:HTTP 协议详解

    参考:https://kb.cnblogs.com/page/130970/#httpmeessagestructe HTTP协议是无状态的 http协议是无状态的,同一个客户端的这次请求和上次请求是 ...

  4. P1131 [ZJOI2007]时态同步【树形dp】

    时态同步 从叶子到根节点统计修改次数.树形\(dp\)思想. 题目描述 小\(Q\)在电子工艺实习课上学习焊接电路板.一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数字\(1,2,3-\). ...

  5. Redis系列(八):发布与订阅

    Redis的发布与订阅,有点类似于消息队列,发送者往频道发送消息,频道的订阅者接收消息. 1. 发布与订阅示例 首先,在本机开启第1个Redis客户端,执行如下命令订阅blog.redis频道: SU ...

  6. JavaScript基础初始时期分支(018)

    Init-Time Branching初始时期分支是一种用做优化的模式.如果某些条件在程序启动后就不再改变,那么我们就只需要在初始时期检查一次就可以了,而不是在每次 需要用到这些条件的时候都检查一次. ...

  7. Zookeeper Watcher 流程分析(结合源码)

    概述 ZK提供了分布式数据的发布/订阅功能,一个典型的发布/订阅模型系统定义了一种一对多的订阅关系,能够让多个订阅者同时监听某个主题对象,当这个主题对象自身状态发生变化时,会通知所有的订阅者.在ZK中 ...

  8. 基本 Docker 命令列表

    docker build -t friendlyname .# 使用此目录的 Dockerfile 创建镜像 docker run -p 4000:80 friendlyname # 运行端口 400 ...

  9. centos7在Evolution中配置163邮箱,被阻止收件解决方法

    config.mail.163.com/settings/imap/login.jsp?uid=xxxx@163.com

  10. h5手机摇一摇功能实现:基于html5重力感应DeviceMotionEvent事件监听手机摇晃

    DeviceMotionEven是html5提供的一个用来获取设备物理方向及运动的信息(比如陀螺仪.罗盘及加速计)的Dom事件,事件描述如下: deviceorientation:提供设备的物理方向信 ...