题意

题意奇奇怪怪,这里就不写了。

\(\texttt{Data Range:}1\leq n\leq 10^5,1\leq m\leq 2\times 10^5\)

题解

为什么你们都是卡在数学方面,难道只有我卡在不晓得怎么维护上面吗

看到下面的题解通篇的泰勒展开,我决定写一篇从 \(\texttt{EGF}\) 上说明的题解,而且公式也比下面的清晰的多。

首先我们做个热身,先来看 \(e^x,\sin x,\cos x\) 对应的 \(\texttt{EGF}\):

\[e^x=\sum\limits_{i=0}^{\infty}\frac{x^i}{i!}
\]
\[\sin x=\sum\limits_{i=0}^{\infty}\frac{(-1)^ix^{2i+1}}{(2i+1)!}
\]
\[\cos x=\sum\limits_{i=0}^{\infty}\frac{(-1)^ix^{2i}}{(2i)!}
\]

接下来我们用 \(ax\) 替换 \(x\) 得到:

\[e^{ax}=\sum\limits_{i=0}^{\infty}\frac{a^ix^i}{i!}
\]
\[\sin (ax)=\sum\limits_{i=0}^{\infty}\frac{(-1)^ia^{2i+1}x^{2i+1}}{(2i+1)!}
\]
\[\cos (ax)=\sum\limits_{i=0}^{\infty}\frac{(-1)^ia^{2i}x^{2i}}{(2i)!}
\]

如果写的更直观一点呢?

\[e^{ax}=1+ax+\frac{a^2x^2}{2!}+\frac{a^3x^3}{3!}+\cdots
\]
\[\sin(ax)=ax-\frac{a^3x^3}{3!}+\frac{a^5x^5}{5!}-\frac{a^7x^7}{7!}+\cdots
\]
\[\cos(ax)=1-\frac{a^2x^2}{2!}+\frac{a^4x^4}{4!}-\frac{a^6x^6}{6!}+\cdots
\]

接下来就是正题了。

考虑到 \(e^{ax+b}=e^{ax}\cdot e^{b}\),而 \(b\) 是给定常数,所以

\[e^{ax+b}=e^b(1+ax+\frac{a^2x^2}{2!}+\frac{a^3x^3}{3!}+\cdots)=\sum\limits_{i=0}^{\infty}\frac{e^ba^ix^i}{i!}
\]

然后根据常见的三角恒等变换公式,我们有

\[\sin(ax+b)=\sin(ax)\cos b+\cos(ax)\sin b
\]

而 \(b\) 是给定的常数,所以

\[\sin(ax+b)=\cos b(ax-\frac{a^3x^3}{3!}+\frac{a^5x^5}{5!}-\frac{a^7x^7}{7!}+\cdots)+\sin b(1-\frac{a^2x^2}{2!}+\frac{a^4x^4}{4!}-\frac{a^6x^6}{6!}+\cdots)
\]
\[\sin(ax+b)=\sum\limits_{i=0}^{\infty}\frac{\cos b(-1)^ia^{2i+1}x^{2i+1}}{(2i+1)!}+\frac{\sin b(-1)^ia^{2i}x^{2i}}{(2i)!}
\]

然后维护一下这些 \(\texttt{EGF}\) 就可以直接做了。我的代码维护到 \(15\) 项,所以比较慢,但还是能过。(至少不用像鰰一样预处理组合数)

代码

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
typedef long double db;
const ll MAXN=2e5+51;
struct Polynomial{
db cof[16];
Polynomial()
{
memset(cof,0,sizeof(cof));
}
inline Polynomial operator +(const Polynomial &rhs)const
{
Polynomial res;
for(register int i=0;i<16;i++)
{
res.cof[i]=cof[i]+rhs.cof[i];
}
return res;
}
inline db eval(db x)
{
db res=0,cur=1;
for(register int i=0;i<16;i++)
{
res+=cof[i]*cur,cur*=x;
}
return res;
}
inline void op()
{
for(register int i=0;i<16;i++)
{
printf("%.8Lf\n",cof[i]);
}
}
};
ll n,m,x,y,typ;
db u,v;
string type,op;
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
namespace LCT{
struct Node{
ll fa,rv,sz;
Polynomial poly,sum;
ll ch[2];
};
struct LinkCutTree{
Node nd[MAXN];
ll st[MAXN];
#define ls nd[x].ch[0]
#define rs nd[x].ch[1]
inline bool nroot(ll x)
{
return nd[nd[x].fa].ch[0]==x||nd[nd[x].fa].ch[1]==x;
}
inline void update(ll x)
{
nd[x].sum=nd[ls].sum+nd[rs].sum+nd[x].poly;
}
inline void reverse(ll x)
{
swap(ls,rs),nd[x].rv^=1;
}
inline void spread(ll x)
{
if(nd[x].rv)
{
ls?reverse(ls):(void)(1),rs?reverse(rs):(void)(1);
nd[x].rv=0;
}
}
inline void rotate(ll x)
{
ll fa=nd[x].fa,gfa=nd[fa].fa;
ll dir=nd[fa].ch[1]==x,son=nd[x].ch[!dir];
if(nroot(fa))
{
nd[gfa].ch[nd[gfa].ch[1]==fa]=x;
}
nd[x].ch[!dir]=fa,nd[fa].ch[dir]=son;
if(son)
{
nd[son].fa=fa;
}
nd[fa].fa=x,nd[x].fa=gfa,update(fa);
}
inline void splay(ll x)
{
ll fa=x,gfa,cur=0;
st[++cur]=fa;
while(nroot(fa))
{
st[++cur]=fa=nd[fa].fa;
}
while(cur)
{
spread(st[cur--]);
}
while(nroot(x))
{
fa=nd[x].fa,gfa=nd[fa].fa;
if(nroot(fa))
{
rotate((nd[fa].ch[0]==x)^(nd[gfa].ch[0]==fa)?x:fa);
}
rotate(x);
}
update(x);
}
inline void access(ll x)
{
for(register int i=0;x;x=nd[i=x].fa)
{
splay(x),rs=i,update(x);
}
}
inline void makeRoot(ll x)
{
access(x),splay(x),reverse(x);
}
inline ll findRoot(ll x)
{
access(x),splay(x);
while(ls)
{
spread(x),x=ls;
}
return x;
}
inline void split(ll x,ll y)
{
makeRoot(x),access(y),splay(y);
}
inline void link(ll x,ll y)
{
makeRoot(x);
if(findRoot(y)!=x)
{
nd[x].fa=y;
}
}
inline void cut(ll x,ll y)
{
makeRoot(x);
if(findRoot(y)==x&&nd[x].fa==y&&!rs)
{
nd[x].fa=nd[y].ch[0]=0,update(y);
}
}
#undef ls
#undef rs
};
}
LCT::LinkCutTree lct;
inline Polynomial sin(db u,db v)
{
Polynomial res;
db sinv=sin(v),cosv=cos(v),pw=1,fact=1;
for(register int i=0;i<16;i++)
{
res.cof[i]=(i&2?-1:1)*(i&1?cosv:sinv)*pw*fact,pw*=u,fact/=(1.0*(i+1));
}
return res;
}
inline Polynomial exp(db u,db v)
{
Polynomial res;
db expv=exp(v),pw=1,fact=1;
for(register int i=0;i<16;i++)
{
res.cof[i]=expv*pw*fact,pw*=u,fact/=1.0*(i+1);
}
return res;
}
inline Polynomial linear(db u,db v)
{
Polynomial res;
res.cof[0]=v,res.cof[1]=u;
return res;
}
int main()
{
n=read(),m=read(),cin>>type;
for(register int i=1;i<=n;i++)
{
typ=read(),scanf("%Lf%Lf",&u,&v);
lct.nd[i].poly=typ==1?sin(u,v):typ==2?exp(u,v):linear(u,v);
}
for(register int i=0;i<m;i++)
{
cin>>op;
if(op=="appear")
{
x=read()+1,y=read()+1,lct.link(x,y);
}
if(op=="disappear")
{
x=read()+1,y=read()+1,lct.cut(x,y);
}
if(op=="magic")
{
x=read()+1,typ=read(),scanf("%Lf%Lf",&u,&v);
lct.splay(x);
lct.nd[x].poly=typ==1?sin(u,v):typ==2?exp(u,v):linear(u,v);
}
if(op=="travel")
{
x=read()+1,y=read()+1,scanf("%Lf",&u);
if(lct.findRoot(x)!=lct.findRoot(y))
{
puts("unreachable");
continue;
}
lct.split(x,y),printf("%.12Lf\n",lct.nd[y].sum.eval(u));
}
}
}

Luogu P4546 [THUWC2017]在美妙的数学王国中畅游的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 题解 洛谷 P4546 【[THUWC2017]在美妙的数学王国中畅游】

    首先发现有连边和删边的操作,所以我们肯定要用\(LCT\)来进行维护. 接下来考虑如何进行\(LCT\)上的信息合并. \(f=1\),则函数为\(f(x)=sin(ax+b)\) \(f=2\),则 ...

  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. Linux系统编程 —互斥量mutex

    互斥量mutex 前文提到,系统中如果存在资源共享,线程间存在竞争,并且没有合理的同步机制的话,会出现数据混乱的现象.为了实现同步机制,Linux中提供了多种方式,其中一种方式为互斥锁mutex(也称 ...

  2. Typora,你好!

    初识Typora 1.标题 一个井号+空格+回车 =一级标题 两个井号+空格+回车 =二级标题 三个井号+空格+回车 =三级标题 四个井号+空格+回车 =四级标题 快捷键的话: 按ctrl + 1 就 ...

  3. 和低效 IO 说再见,回头补一波 Java 7 的 NIO.2 特性

    其实在这之前已经写过一篇关于 Java 7 的新特性文章了,那篇文章主要介绍了 Java 7 的资源自动关闭.Switch String 实现原理.异常捕获 try-catch.新的二进制书写方式等, ...

  4. RabbitMQ 3.6.12延迟队列简单示例

    简介 延迟队列存储的消息是不希望被消费者立刻拿到的,而是等待特定时间后,消费者才能拿到这个消息进行消费.使用场景比较多,例如订单限时30分钟内支付,否则取消,再如分布式环境中每隔一段时间重复执行某操作 ...

  5. Java泛型中的类型参数和通配符类型

    类型参数 泛型有三种实现方式,分别是泛型接口.泛型类.泛型方法,下面通过泛型方法来介绍什么是类型参数. 泛型方法声明方式:访问修饰符 <T,K,S...> 返回类型 方法名(方法参数){方 ...

  6. MySQL数据备份脚本

    #!/bin/bash ############################# # time:20191210 # fage trainning ######################### ...

  7. ORA-28001: the password has expired 密码已过期

    ORA-28001: the password has expiredORA-28001: 密码已过期 Cause:       The user's account has expired and ...

  8. Fiddler抓包工具 请求图标为一个锁的图标的设置

    第一步,Fiddler抓包的数据 前面的都是一个锁的图标,的设置方法, 然后 点击打开 按此设置图一 在图二, 图三. 其他默认就好

  9. 第一个月多测师讲解__项目讲解以及注意事项(肖sir)

    一.目的讲解流程:(讲述业务时长10-15分钟为宜)1.自我介绍礼貌用语,姓名,籍贯,学校,个人技能,经验,表现,兴趣爱好等 ,1分钟 ,谢谢2.介绍项目的名字 ,项目的背景,(涉及什么架构)3.对项 ...

  10. python 不定长参数

    1 #不定长参数 * 元祖 ** 字典 2 def item(a,b,*c,**d): 3 print(a) 4 print(b) 5 print(c) 6 print(d) 7 8 item(11, ...