BZOJ5020: [THUWC 2017]在美妙的数学王国中畅游

其实题面好像有点不全,建议去洛谷:

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

这里还是$BZOJ$的题面。

Description

数字和数学规律主宰着这个世界。
机器的运转,
生命的消长,
宇宙的进程,
这些神秘而又美妙的过程无不可以用数学的语言展现出来。
这印证了一句古老的名言:
“学好数理化,走遍天下都不怕。”
学渣小R被大学的数学课程虐得生活不能自理,微积分的成绩曾是他在教室里上的课的最低分。然而他的某位陈姓室友却能轻松地在数学考试中得到满分。为了提升自己的数学课成绩,有一天晚上(在他睡觉的时候),他来到了数学王国。
数学王国中,每个人的智商可以用一个属于 [0,1]的实数表示。数学王国中有 n 个城市,编号从 0 到 n−1 ,这些城市由若干座魔法桥连接。每个城市的中心都有一个魔法球,每个魔法球中藏有一道数学题。每个人在做完这道数学题之后都会得到一个在 [0,1] 区间内的分数。一道题可以用一个从 [0,1] 映射到 [0,1]的函数 f(x) 表示。若一个人的智商为 x ,则他做完这道数学题之后会得到 f(x)分。函数 f有三种形式:
正弦函数 sin(ax+b) (a∈[0,1],b∈[0,π],a+b∈[0,π])
指数函数 e^(ax+b) (a∈[−1,1],b∈[−2,0],a+b∈[−2,0])
一次函数 ax+b (a∈[−1,1],b∈[0,1],a+b∈[0,1]
数学王国中的魔法桥会发生变化,有时会有一座魔法桥消失,有时会有一座魔法桥出现。但在任意时刻,只存在至多一条连接任意两个城市的简单路径(即所有城市形成一个森林)。在初始情况下,数学王国中不存在任何的魔法桥。
数学王国的国王拉格朗日很乐意传授小R数学知识,但前提是小R要先回答国王的问题。这些问题具有相同的形式,即一个智商为 x 的人从城市 u 旅行到城市 v(即经过 u 到 v 这条路径上的所有城市,包括 u和 v )且做了所有城市内的数学题后,他所有得分的总和是多少。

Input

第一行两个正整数 n,m 和一个字符串 type 。
表示数学王国中共有 n 座城市,发生了 m 个事件,该数据的类型为 type 。 
typet 字符串是为了能让大家更方便地获得部分分,你可能不需要用到这个输入。
其具体含义在【数据范围与提示】中有解释。
接下来 n 行,第 i 行表示初始情况下编号为 i 的城市的魔法球中的函数。
一个魔法用一个整数 f表示函数的类型,两个实数 a,b 表示函数的参数,若
f=1,则函数为 f(x)=sin(ax+b)(a∈[0,1],b∈[0,π],a+b∈[0,π])
f=2,则函数为 f(x)=e^(ax+b)(a∈[−1,1],b∈[−2,0],a+b∈[−2,0])
f=3,则函数为 f(x)=ax+b(a∈[−1,1],b∈[0,1],a+b∈[0,1])
接下来 m行,每行描述一个事件,事件分为四类。
appear u v 表示数学王国中出现了一条连接 u 和 v 这两座城市的魔法桥 (0≤u,v<n,u≠v) ,保证连接前 u和 v 这两座城市不能互相到达。
disappear u v 表示数学王国中连接 u 和 v 这两座城市的魔法桥消失了,保证这座魔法桥是存在的。
magic c f a b 表示城市 c 的魔法球中的魔法变成了类型为 f ,参数为 a,b 的函数
travel u v x 表示询问一个智商为 x 的人从城市 u 旅行到城市 v 
(即经过 u到 v 这条路径上的所有城市,包括 u 和 v )后,他得分的总和是多少。
若无法从 u 到达 v ,则输出一行一个字符串 unreachable。
1≤n≤100000,1≤m≤200000

Output

对于每个询问,输出一行实数,表示得分的总和。

Sample Input

3 7 C1
1 1 0
3 0.5 0.5
3 -0.5 0.7
appear 0 1
travel 0 1 0.3
appear 0 2
travel 1 2 0.5
disappear 0 1
appear 1 2
travel 1 2 0.5

Sample Output

9.45520207e-001
1.67942554e+000
1.20000000e+000

题解Here!

数字和数学规律主宰着这个世界。。。

学好数理化,走遍天下都不怕。。。

这个题要是没有询问就是一个沙茶$LCT$。
但是这个询问很难搞。。。
现在的$LCT$怎么都和一些奇奇怪怪的东西搞在一起。。。

其实原题面有一个提示,我们称它为——泰勒展开

如下:(选自洛谷)

若函数$f(x)$的$n$阶导数在$[a,b]$区间内连续,则对$f(x)$在$x_0(x_0\in[a,b])$处使用$n$次拉格朗日中值定理可以得到带拉格朗日余项的泰勒展开式:

$$f(x)=f(x_0)+\frac{f'(x_0)(x-x_0)}{1!}+\frac{f''(x_0)(x-x_0)^2}{2!}+ \cdots +\frac{f^{(n-1)}(x_0)(x-x_0)^{n-1}}{(n-1)!}+\frac{f^{(n)}(\xi)(x-x_0)^n}{n!},x\in[a,b]$$

其中,当$x>x_0$时,$\xi\in[x_0,x]$;当$x<x_0$时,$\xi\in[x,x_0]$。

$f^{(n)}(x)$表示函数$f(x)$的$n$阶导数。

其实别看这么多乱七八糟的名词,关键就在于那个式子。

我们注意到,等号的左边是$f(x)$!

也就是说,我们可以不用搞其它的东西,只要把$f(x)$的$n$阶导数搞出来就好。

什么?你不知道导数?

回去学《数学 选修2-2》去吧。。。

这里给出此题要用到的导数计算:

基本公式:

$$f(x)=x\quad\Rightarrow\quad f'(x)=1$$

$$f(x)=\sin(x)\quad\Rightarrow\quad f'(x)=\cos(x)$$

$$f(x)=\cos(x)\quad\Rightarrow\quad f'(x)=-\sin(x)$$

$$f(x)=e^x\quad\Rightarrow\quad f'(x)=e^x$$

计算公式:

$$[f(x)+g(x)]'=f'(x)+g'(x)$$

$$[f(x)g(x)]'=f'(x)g(x)+f(x)g'(x)$$

$$\text{链式法则:}[f(g(x))]'=f'(g(x))\times g'(x)$$

于是我们可以愉快地推式子了!

以$f(x)=sin(x)$为例:

泰勒展开式中选取了一个$x_0$,我们为了方便,直接$x_0=0$。

设$f^n(x)$为$f(x)$的$n$阶导数。

那么:$$f(x)=f(0)+\frac{f^1(0)(x-0)}{1!}+\frac{f^2(0)(x-0)^2}{2!}+ \cdots +\frac{f^{n-1}(0)(x-0)^{n-1}}{(n-1)!}+\frac{f^{n}(\xi)(x-0)^n}{n!}$$

化简一下:$$f(x)=f(0)+\frac{f^1(0)}{1!}x+\frac{f^2(0)}{2!}x^2+ \cdots +\frac{f^{n-1}(0)}{(n-1)!}x^{n-1}+\frac{f^{n}(\xi)}{n!}x^n$$

但是这个$n$到底是多大呢?

其实,我们发现$n!$在$n$比较小时就是暴增函数。

也就是说,越往后的项对答案贡献越小,而精度也有$SPJ$,所以我们并不需要末尾那么多项。

这里我选取了$n=16$这个值,这是可以过的。

于是我们只要对每个点维护$16$项多项式就好。

但是又有人问了:题目中不是求$f(x)=sin(ax+b)$吗?

其实根据上面那个链式法则我们可以得出:$$f(x)=\sin(ax+b)\quad\Rightarrow\quad f'(x)=a\cos(ax+b)$$

同理对于另外两个式子有:

$$f(x)=ax+b\quad\Rightarrow\quad f'(x)=a$$

$$f(x)=e^{ax+b}\quad\Rightarrow\quad f'(x)=ae^{ax+b}$$

但是这只是一阶导数啊,高阶导数怎么办?

对于$f(x)=ax+b$,只有一阶导数$f'(x)=a$,高阶导数全部为$0$。

对于$f(x)=e^{ax+b}$,一阶导数$f'(x)=ae^{ax+b}$,然后每高一阶多乘一个$a$,如二阶导数为$f''(x)=a^2e^{ax+b}$。

对于$f(x)=\sin(ax+b)$,一阶导数$f'(x)=a\cos(ax+b)$,然后每高一阶多乘一个$a$,$\text{阶数}\mod 2==0$的导数为$\sin$,否则为$\cos$,并且$\text{阶数}\mod 4\leq1$的导数为正,否则为负。

由于精度会出锅,再加上每次计算$\sin(x),\cos(x),e^x$会比较慢,于是每次计算之前预处理一下即可。

至于阶乘。。。我一开始写了个逆元,发现模数不知道。。。

我这个大制杖好久才反应过来$16!=2.0922789888\times 10^{13}<10^{18}$。。。

所以直接开$double$预处理阶乘就好。

$LCT$应该不用多说,维护多项式的每一项单独的和。

答案就是多项式每一项之和。

至于那个什么科学计数法。。。大多数人直接$\%.8lf$。。。

其实我们可以直接用$C++$的自带版本——$\%.8e$!

自动将小数转成科学计数法!

还有啥细节那就看代码吧。。。

附代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#define MAXN 100010
#define MAXM 20
using namespace std;
int n,m;
double fact[MAXM],val[MAXN][MAXM];
int top,stack[MAXN];
struct Link_Cut_Tree{int f,flag,son[2];double v[MAXM];
}a[MAXN];
inline int read(){int date=0,w=1;char c=0;while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}return date*w;
}
inline bool isroot(int rt){return a[a[rt].f].son[0]!=rt&&a[a[rt].f].son[1]!=rt;
}
inline void pushup(int rt){if(!rt)return;for(int i=0;i<=15;i++)a[rt].v[i]=a[a[rt].son[0]].v[i]+a[a[rt].son[1]].v[i]+val[rt][i];
}
inline void pushdown(int rt){if(!rt||!a[rt].flag)return;a[a[rt].son[0]].flag^=1;a[a[rt].son[1]].flag^=1;a[rt].flag^=1;swap(a[rt].son[0],a[rt].son[1]);
}
inline void turn(int rt){int x=a[rt].f,y=a[x].f,k=a[x].son[0]==rt?1:0;if(!isroot(x)){if(a[y].son[0]==x)a[y].son[0]=rt;else a[y].son[1]=rt;}a[rt].f=y;a[x].f=rt;a[a[rt].son[k]].f=x;a[x].son[k^1]=a[rt].son[k];a[rt].son[k]=x;pushup(x);pushup(rt);
}
void splay(int rt){top=0;stack[++top]=rt;for(int i=rt;!isroot(i);i=a[i].f)stack[++top]=a[i].f;while(top)pushdown(stack[top--]);while(!isroot(rt)){int x=a[rt].f,y=a[x].f;if(!isroot(x)){if((a[y].son[0]==x)^(a[x].son[0]==rt))turn(rt);else turn(x);}turn(rt);}
}
void access(int rt){for(int i=0;rt;i=rt,rt=a[rt].f){splay(rt);a[rt].son[1]=i;pushup(rt);}
}
inline void makeroot(int rt){access(rt);splay(rt);a[rt].flag^=1;}
int findroot(int rt){access(rt);splay(rt);while(a[rt].son[0])rt=a[rt].son[0];return rt;
}
inline void split(int x,int y){makeroot(x);access(y);splay(y);}
inline void link(int x,int y){makeroot(x);a[x].f=y;}
inline void cut(int x,int y){split(x,y);if(a[y].son[0]==x&&a[x].f==y&&!a[x].son[1])a[x].f=a[y].son[0]=0;
}
void change(int x,int f,double a,double b){memset(val[x],0,sizeof(val[x]));if(f==1){double t=1,Sin=sin(b),Cos=cos(b);for(int i=0;i<=15;i++){val[x][i]=((i%2)?Cos:Sin)*((i%4<=1)?1:-1)*t/fact[i];t*=a;}}else if(f==2){double t=1,Exp=exp(b);for(int i=0;i<=15;i++){val[x][i]=Exp*t/fact[i];t*=a;}}else{val[x][0]=b;val[x][1]=a;}
}
double query(int x,int y,double k){split(x,y);double s=0,t=1;for(int i=0;i<=15;i++){s+=a[y].v[i]*t;t*=k;}return s;
}
void work(){int u,v;double x,y,k;char ch[20];while(m--){scanf("%s",ch);u=read();v=read();switch(ch[0]){case 'a':{u++;v++;link(u,v);break;}case 'd':{u++;v++;cut(u,v);break;}case 'm':{u++;access(u);splay(u);scanf("%lf%lf",&x,&y);change(u,v,x,y);pushup(u);break;}case 't':{u++;v++;scanf("%lf",&k);if(findroot(u)!=findroot(v))printf("unreachable\n");else printf("%.8e\n",query(u,v,k));break;}}}
}
void init(){int f;double x,y;char ch[5];n=read();m=read();scanf("%s",ch);fact[0]=1;for(int i=1;i<=16;i++)fact[i]=fact[i-1]*i;for(int i=1;i<=n;i++){f=read();scanf("%lf%lf",&x,&y);change(i,f,x,y);}
}
int main(){init();work();return 0;
}

转载于:https://www.cnblogs.com/Yangrui-Blog/p/10466865.html

BZOJ5020: [THUWC 2017]在美妙的数学王国中畅游相关推荐

  1. BZOJ5020: [THUWC 2017]在美妙的数学王国中畅游(LCT,泰勒展开,二项式定理)

    Description 数字和数学规律主宰着这个世界.   机器的运转,   生命的消长,   宇宙的进程,   这些神秘而又美妙的过程无不可以用数学的语言展现出来.   这印证了一句古老的名言:   ...

  2. [BZOJ5020] [THUWC 2017]在美妙的数学王国中畅游

    Description 数字和数学规律主宰着这个世界. 机器的运转, 生命的消长, 宇宙的进程, 这些神秘而又美妙的过程无不可以用数学的语言展现出来. 这印证了一句古老的名言: "学好数理化 ...

  3. [bzoj5020][THUWC 2017]在美妙的数学王国中畅游

    Orz w_yqts lct+泰勒展开 #include <bits/stdc++.h> using namespace std; #define db double #define N ...

  4. bzoj5020[THUWC 2017]在美妙的数学王国中畅游(LCT)

    传送门:https://loj.ac/problem/2289 https://www.lydsy.com/JudgeOnline/problem.php?id=5020 solutionsoluti ...

  5. [BZOJ5020][THUWC 2017]在美妙的数学王国中畅游(LCT + 一点数学知识)

    Address 洛谷 P4546 BZOJ 5020 LOJ #2289 Solution 如果只有一次函数 ax+bax+bax+b ,那么这是非常裸的 LCT ,维护 aaa 之和与 bbb 之和 ...

  6. 【BZOJ5020】[THUWC 2017]在美妙的数学王国中畅游 泰勒展开+LCT

    [BZOJ5020][THUWC 2017]在美妙的数学王国中畅游 Description 数字和数学规律主宰着这个世界. 机器的运转, 生命的消长, 宇宙的进程, 这些神秘而又美妙的过程无不可以用数 ...

  7. 【bzoj5020】[THUWC 2017]在美妙的数学王国中畅游 泰勒展开+LCT

    题目描述 学渣小R被大学的数学课程虐得生活不能自理,微积分的成绩曾是他在教室里上的课的最低分.然而他的某位陈姓室友却能轻松地在数学考试中得到满分.为了提升自己的数学课成绩,有一天晚上(在他睡觉的时候) ...

  8. 解题:THUWC 2017 在美妙的数学王国中畅游

    题面 _"数字和数学规律主宰着这个世界."_ 在 @i207M 帮助下折腾了半天终于搞懂了导数和泰勒展开,引用某学长在考场上的感受:感觉整个人都泰勒展开了 显然是个奇奇怪怪的东西套 ...

  9. [THUWC 2017]在美妙的数学王国中畅游

    LOJ2289 看到加边减边想到LCT 猜到要合并函数,然后看到"小R教你学数学" 果断泰勒展开 以下所有结果均令x0=0x_0=0x0​=0 sin⁡(ax+b)=sin⁡(b) ...

最新文章

  1. Hibernate 的 session.load()使用方法
  2. 独家 | 集成学习入门介绍
  3. 【计算机网络】应用层 : DNS 域名解析系统 ( 域名 | 域名服务器 | 域名解析过程 | 递归查询 | 迭代查询 | 高速缓存 )
  4. HDU——2064汉诺塔III
  5. Spring data jpa 条件查询-按时间段查询
  6. eclipse再次导入已经逻辑删除的工程,IDE提示已存在,无法导入的解决办法
  7. SAP Spartacus cxFocus的config属性的赋值原理
  8. 【学习笔记】我命由天不由我之随机化庇佑 —— 爬山法 和 模拟退火法
  9. SpringCloud Hoxton版微服务- Ribbon实现负载均衡
  10. VIM打造GTK编程环境
  11. Silverlight 4+RIA Services–搜索引擎优化(SEO)
  12. 又一可获Linux、Unix根权限的漏洞曝出
  13. 使用DotNetOpenAuth搭建OAuth2.0授权框架——Demo代码简单说明
  14. C++ STL容器在for循环中删除迭代器 正确方法 it++正确吗
  15. android 远程连接电脑屏幕,Android安卓手机3389远程连接电脑桌面教程
  16. Android 9.0系统源码_包管理机制(二)PackageInstaller安装APK
  17. 用别人的血汗去染自己的红顶子,谁愿意去干谁干,我是不干
  18. 爬虫一:用正则表达式爬取图片
  19. 杰理之AUDIO_DAC【篇】
  20. 计算机输入法切换用户登录,在电脑上如何设置输入法全局切换的功能

热门文章

  1. [缓存]迅雷(XUNLEI)的工作原理揭密
  2. Delphi中使用ListView和TreeView的Item中的Data可能被忽略的内存泄漏
  3. python下载文件到指定文件夹-python实现指定文件夹下的指定文件移动到指定位置...
  4. python真的这么厉害吗-嗯?python居然可以这么嚣张?这么厉害!到底是为什么?...
  5. 青少年软件编程等级考试 python-中国电子学会、北大等推出青少年软件编程等级标准升级版...
  6. python爬虫教程入门-Python爬虫系列 - 入门教学
  7. python下载地址-python下载网址
  8. python怎么导入视频-Python模块导入详解
  9. 财务需要学python-财务人要学Python吗?
  10. 适合自学python的图书-有哪些适合零编程基础的人学习Python的书?