题意

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

\(\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. Alink漫谈(二十二) :源码分析之聚类评估

    Alink漫谈(二十二) :源码分析之聚类评估 目录 Alink漫谈(二十二) :源码分析之聚类评估 0x00 摘要 0x01 背景概念 1.1 什么是聚类 1.2 聚类分析的方法 1.3 聚类评估 ...

  2. Java8——Stream流式操作的一点小总结

    我发现,自从我学了Stream流式操作之后,工作中使用到的频率还是挺高的,因为stream配合着lambda表达式或者双冒号(::)使用真的是优雅到了极致!今天就简单分(搬)享(运)一下我对strea ...

  3. JUC 常用4大并发工具类

    什么是JUC? JUC就是java.util.concurrent包,这个包俗称JUC,里面都是解决并发问题的一些东西 该包的位置位于java下面的rt.jar包下面 4大常用并发工具类: Count ...

  4. vue项目中视频播放结束返回首页出现1秒左右的白屏问题

    vue项目的性能优化问题,一直以来都是大家比较关注的. 近日负责的项目中,使用了SignalR实时通讯,客户端中点击发起播放视频的请求到服务器,服务器接到请求后再调用前端的播放视频方法,以此来达到播放 ...

  5. WEB通信及前后端组成

    NDS(域名系统) 按个人的理解,就是将域名和IP映射,通过输入域名,DNS 找到对应的域名的IP地址,即可访问. NDS请求步骤: 当用户输入域名(例:www.baidu.com),回车那一刻: 1 ...

  6. 数论(8):min_25 筛(扩展埃氏筛)

    min_25 筛介绍 我们考虑这样一个问题. \[ans=\sum_{i = 1}^nf(i)\\ \] 其中 \(1 \le n \le 10^{10}\) 其中 \(f(i)\) 是一个奇怪的函数 ...

  7. Linux一些基础命令

    man              查看命令                                                                             -  ...

  8. 给子元素设置margin-top无效果的一种解决方法

    在写一个登陆界面的时候,设置登录按钮的margin-top时出了问题 先是这么写的 <div style="margin-top:30px"> <a style= ...

  9. 【题解】[SHOI2007]善意的投票 / [JLOI2010]冠军调查

    Link \(\text{Solution:}\) 我们令源点和汇点分别为睡觉和不睡觉这两种互斥的决策点.把小朋友看成点,问题转化为最小割. 每一个小朋友对自己的意愿指向的汇点/源点.容量为\(1.\ ...

  10. SpringBoot整合Shiro+MD5+Salt+Redis实现认证和动态权限管理(上)----筑基中期

    写在前面 通过前几篇文章的学习,我们从大体上了解了shiro关于认证和授权方面的应用.在接下来的文章当中,我将通过一个demo,带领大家搭建一个SpringBoot整合Shiro的一个项目开发脚手架, ...