题意

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

\(\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. PyCharm-缩进 格式化代码

    格式化代码 Ctrl + Alt + l 缩进代码 Tab    向右缩进4格 Shift + Tab 向左缩进4格

  2. 理解pytorch几个高级选择函数(如gather)

    目录 1. 引言 2. 维度的理解 3. gather函数 4. index_select函数 5. masked_select函数 6. nonzero函数 1. 引言   最近在刷开源的Pytor ...

  3. 概率派VS贝叶斯派

    机器学习中的MLE和MAP两大学派的争论: 频率学派 - Frequentist - Maximum Likelihood Estimation (MLE,最大似然估计): 频率学派认为世界是确定的, ...

  4. HTML+CSS系列:登录界面实现

    一.效果 二.具体实现 1.index.html <!DOCTYPE html> <html> <head> <meta charset="utf- ...

  5. mysql5.7开启慢查询日志

    环境:centos7 mysql版本:5.7.28 一.什么是慢查询 MySQL默认10s内没有响应SQL结果,则为慢查询 当然我们也可以修改这个默认时间 查看慢查询的时间 show variable ...

  6. 005 01 Android 零基础入门 01 Java基础语法 01 Java初识 05 Eclipse简介

    005 01 Android 零基础入门 01 Java基础语法 01 Java初识 05 Eclipse简介 Eclipse是一款集成开发工具--IDE. 集成开发环境(IDE,Integrated ...

  7. matlab中strcmpi比较字符串(不区分大小写)

    来源:https://ww2.mathworks.cn/help/matlab/ref/strcmpi.html?searchHighlight=strcmpi&s_tid=doc_srcht ...

  8. windev的内部窗口传参方式及其与类的相似性

    最近的应用,需要向一个内部窗口(internal window)传参,因为官方文档的说明较为宽泛,虽然结果只有两小段代码,但也费了很大的劲.把所有关于procedure的文档看一遍,又是重新学习了一遍 ...

  9. java中文件是否为空

    在File类中并没有提供判断文件是否为空的方法,但可以借助length()方法的返回值进行判断.如果文件不存在或文件为空时,length()方法返回0. File file = new File(&q ...

  10. 以太坊blockchain源码分析

    blockchain关键元素 db:持久化到底层数据储存,即leveldb: genesisBlock:创始区块 currentBlock:当前区块,blockchain中并不是储存链所有的block ...