「LOJ 2289」「THUWC 2017」在美妙的数学王国中畅游——LCT&泰勒展开
题目大意:
给一个动态树,每个节点上维护一个函数为$f(x)=sin(ax+b)$、$f(x)=e^{ax+b}$、$f(x)=ax+b$中的一个。
支持删边连边,修改节点上函数的操作。
每次询问$u$到$v$路径上所有函数带入$x$值的和。
题解:
给了个泰勒公式
(粘贴自百度)
不过……要是会导数这题也应该知道……不会导数给了也是白给……不知道出题人怎么想的……
话说直接给麦克劳林展开+导数不好吗……
因为$f(x)=e^x$的导数$f'(x)=e^x$所有当取$x_0=0$时就有其麦克劳林展开:
$f(x)=e^x=\sum_{i=0}^{\infty}\frac{x^i}{i!}$
而$sin(x)$导数为$cos(x)$,$cos(x)$导数为$-sin(x)$。所以当$x_0=0$时发现$f(x)$奇数$i$阶导数为$(-1)^{\frac{i-1}{2}}$,偶数阶导均为0。有其麦克劳林展开:
$f(x)=\sum_{i=0}^{\infty}\ (-1)^i \frac{ x^{2i+i} }{(2i+i)!}$
考虑这题数据范围不需要展开太多,大概20项就够了。
然后把给的参数$ax+b$带进去得到一个关于$x$的长度为20的多项式,我们LCT的时候维护链上系数和即可。
代码:
#include "bits/stdc++.h"
inline int read (){
int s=0,k=1;char ch=getchar();
while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
return s*k;
}
#define double long double
using namespace std;
const int N=1e5+10;
int C[20][20];
long long fac[20];
inline void init() {
register int i,j;
for (C[0][0]=i=1;i<20;++i)
for (C[i][0]=j=1;j<=i;++j)
C[i][j]=C[i-1][j]+C[i-1][j-1];
for (fac[0]=i=1;i<20;++i)
fac[i]=fac[i-1]*i;
}
namespace LCT {
#define rev(t) (t?t->rev^=1:0)
#define is_root(t) (!t->fa||(t->fa->son[0]!=t&&t->fa->son[1]!=t))
#define son(t) (t->fa->son[1]==t)
#define size(t,s) (t?t->size[s]:0)
struct node {
node () {fa=son[0]=son[1]=NULL,rev=0,memset(self,0,sizeof self),memset(size,0,sizeof size);}
node *fa,*son[2];
double self[20],size[20];
int rev;
inline void pushdown() {
if (!rev) return ;
swap(son[0],son[1]);
rev(son[0]),rev(son[1]);
rev=0;
}
inline void update() {
for (int i=0;i<20;++i)
size[i]=size(son[0],i)+size(son[1],i)+self[i];
}
inline double ans(double x) {
double ans=0,now=1.0;
for (int i=0;i<20;++i,now*=x)
ans+=now*size[i];
return ans;
}
inline void calc(int type,double a[],double b[]) {
memset(self,0,sizeof self);
if (type==1) {
for (int i=0;i<20;++i) if (i%2)
for (int j=0;j<=i;++j) {
self[j]+=((((i-1)/2)&1)?-1:1)*a[j]*b[i-j]*C[i][j]/fac[i];
}
}else if(type==2) {
for (int i=0;i<20;++i)
for (int j=0;j<=i;++j)
self[j]+=a[j]*b[i-j]*C[i][j]/fac[i];
}else self[0]=b[1],self[1]=a[1];
}
}tree[N],*tmp[N];
inline void rotate(node *p){
int a=son(p)^1;node *f=p->fa;
f->son[a^1]=p->son[a];
if (p->son[a]) p->son[a]->fa=f;
p->fa=f->fa;
if (!is_root(f)) f->fa->son[son(f)]=p;
f->fa=p,p->son[a]=f,f->update(),p->update();
}
inline void update(node *p){
if (!is_root(p)) update(p->fa);
p->pushdown();
}
inline void splay(node *p){
register int pos=0;
for(node *t=p;;t=t->fa){
tmp[++pos]=t;
if(is_root(t)) break;
}
for(;pos;--pos) tmp[pos]->pushdown();
for(;!is_root(p);rotate(p))
if(!is_root(p->fa)) rotate(son(p)==son(p->fa)?p->fa:p);
}
inline void access(node *p){
for(node *pre=NULL;p;pre=p,p=p->fa)
splay(p),p->son[1]=pre,p->update();
}
inline void make_root(node *x) {
access(x),splay(x),x->rev^=1;
}
inline void link(node *x,node *y) {
make_root(x);access(y),splay(y),x->fa=y;
y->update();
}
inline void cut(node *x,node *y){
make_root(x),access(y),splay(y);
x->fa=y->son[0]=NULL;y->update();
}
inline double query(node *x,node *y,double xx){
make_root(x),access(y),splay(y);
return y->ans(xx);
}
inline int finds(node *x) {
access(x),splay(x);
while (x->son[0]) x=x->son[0],x->pushdown();
return x-tree;
}
}
int n,m;
double a[20],b[20];
int main (int argc, char const* argv[]){
//freopen("2289.in","r",stdin);
init();
char opt[20];
n=read(),m=read(),scanf("%s",opt);
int type;
a[0]=b[0]=1.0;
using namespace LCT;
for (int i=1;i<=n;++i) {
type=read();
scanf("%Lf%Lf",a+1,b+1);
for (int j=2;j<20;++j)
a[j]=a[j-1]*a[1],
b[j]=b[j-1]*b[1];
tree[i].calc(type,a,b);
}
int u,v,c;
double x;
while (m--) {
scanf("%s",opt);
if (opt[0]=='a') {
u=read()+1,v=read()+1;
link(&tree[u],&tree[v]);
}else if (opt[0]=='d') {
u=read()+1,v=read()+1;
cut(&tree[u],&tree[v]);
}
else if (opt[0]=='m') {
c=read()+1,type=read();
scanf("%Lf%Lf",a+1,b+1);
for (int j=2;j<20;++j)
a[j]=a[j-1]*a[1],
b[j]=b[j-1]*b[1];
make_root(&tree[c]);
tree[c].calc(type,a,b);
tree[c].update();
}
else {
u=read()+1,v=read()+1;
scanf("%Lf",&x);
if (finds(&tree[u])^finds(&tree[v])) {
puts("unreachable");
}
else {
printf("%.8Le\n",query(&tree[u],&tree[v],x));
}
}
}
return 0;
}
「LOJ 2289」「THUWC 2017」在美妙的数学王国中畅游——LCT&泰勒展开的更多相关文章
- bzoj5020 & loj2289 [THUWC 2017]在美妙的数学王国中畅游 LCT + 泰勒展开
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5020 https://loj.ac/problem/2289 题解 这个 appear 和 d ...
- 【THUWC 2017】在美妙的数学王国中畅游
数学王国里有n座城市,每座城市有三个参数\(f\),\(a\),\(b\),一个智商为\(x\)的人经过一座城市的获益\(f(x)\)是 若\(f=1\),则\(f(x)=\sin(ax+b)\): ...
- bzoj 5020(洛谷4546) [THUWC 2017]在美妙的数学王国中畅游——LCT+泰勒展开
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5020 https://www.luogu.org/problemnew/show/P4546 ...
- BZOJ5020: [THUWC 2017]在美妙的数学王国中畅游(LCT,泰勒展开,二项式定理)
Description 数字和数学规律主宰着这个世界. 机器的运转, 生命的消长, 宇宙的进程, 这些神秘而又美妙的过程无不可以用数学的语言展现出来. 这印证了一句古老的名言: ...
- BZOJ5020 [THUWC 2017]在美妙的数学王国中畅游LCT
题意很明显是要用LCT来维护森林 难点在于如何处理函数之间的关系 我们可以根据题目给的提示关于泰勒展开的式子 将三种函数变成泰勒展开的形式 因为$x∈[0,1]$ 所以我们可以将三个函数在$x_0=0 ...
- loj2289 [THUWC 2017]在美妙的数学王国中畅游(LCT+Taylor展开)
link 题目大意: 你需要维护一个树 每个点都有个sin(ax+b)或exp(ax+b)或ax+b 你需要维护一些操作:连边.删边.修改某个点的初等函数.询问某条树链上所有函数带入某个值后权值和或不 ...
- bzoj 5020: [THUWC 2017]在美妙的数学王国中畅游【泰勒展开+LCT】
参考:https://www.cnblogs.com/CQzhangyu/p/7500328.html --其实理解了泰勒展开之后就是水题呢可是我还是用了两天时间来搞懂啊 泰勒展开是到正无穷的,但是因 ...
- 【BZOJ5020】[THUWC 2017]在美妙的数学王国中畅游 泰勒展开+LCT
[BZOJ5020][THUWC 2017]在美妙的数学王国中畅游 Description 数字和数学规律主宰着这个世界. 机器的运转, 生命的消长, 宇宙的进程, 这些神秘而又美妙的过程无不可以用数 ...
- 【LOJ】#2289. 「THUWC 2017」在美妙的数学王国中畅游
题解 我们发现,题目告诉我们这个东西就是一个lct 首先,如果只有3,问题就非常简单了,我们算出所有a的总和,所有b的总和就好了 要是1和2也是多项式就好了--其实可以!也就是下面泰勒展开的用处,我们 ...
随机推荐
- Linux下安装MQ
1.下载Linux下MQ的安装包,网上下载试用版或购买正版,此处以7.0.0.0版为例安装 2.如上图所示,是linux的MQ安装包展开图 3.创建用户和用户组 >root用户连接linux & ...
- 初识JAVA——流程控制之if语句
if语句的流程控制主要分为3种:1,单分支结构:if(){……}: 2,双分支结构:if(){……}else{……}; 3,多分枝结构:if(){……}else if(){……}…… 其中作为if语句 ...
- Day9 进程理论 开启进程的两种方式 多进程实现并发套接字 join方法 Process对象的其他属性或者方法 守护进程 操作系统介绍
操作系统简介(转自林海峰老师博客介绍) #一 操作系统的作用: 1:隐藏丑陋复杂的硬件接口,提供良好的抽象接口 2:管理.调度进程,并且将多个进程对硬件的竞争变得有序 #二 多道技术: 1.产生背景: ...
- 食物链-HZUN寒假集训
食物链 总时间限制: 1000ms 内存限制: 65536kB 描述 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动 ...
- SQL Server 表的管理_关于事务的处理的详解(案例代码)
SQL Server 表的管理_关于事务的处理的详解(案例代码) 一.SQL 事务 1.1SQL 事务 ●事务是在数据库上按照一定的逻辑顺序执行的任务序列,既可以由用户手动执行,也可以由某种数据库程序 ...
- 获取radio、select、checkbox标签选中的值
<input type="radio" id="radio1" name="radio"><label for=" ...
- 在Windows上安装FFmpeg程序的方法(you-get下载视频必备程序)
FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/视频编解码库libavcodec. 该程序 ...
- PermutationTwo
Description: Given a collection of numbers that might contain duplicates, return all possible unique ...
- c#学习笔记 day_one
C#学习笔记 day one Chapter 1 c#概述 1.1 c#概述 C#是微软设计的,简洁的,类型安全的,面向对象的语言.它以c/c++作为基础.它的开发环境是visual studio,最 ...
- 我们常说的 CAS 自旋锁是什么
CAS(Compare and swap),即比较并交换,也是实现我们平时所说的自旋锁或乐观锁的核心操作. 它的实现很简单,就是用一个预期的值和内存值进行比较,如果两个值相等,就用预期的值替换内存值, ...