题目大意

  给你一棵树,每个点有一个函数\(f(x)\)

  • 正弦函数 \(\sin(ax+b) (a\in[0,1],b\in[0,\pi],a+b\in[0,\pi])\)
  • 指数函数 \(e^{ax+b} (a\in[−1,1],b\in[−2,0],a+b\in[−2,0])\)
  • 一次函数 \(ax+b (a\in[−1,1],b\in[0,1],a+b\in[0,1])\)

  还有一些操作:

  • 操作1:连接两个点(保证连接完后还是森林)
  • 操作2:断开两个点之间的边
  • 操作3:修改某一个点的函数
  • 操作4:询问两个点路径上的所有函数的\(f(v)\)的和。

  \(n\leq 100000,m\leq 200000,0\leq v\leq 1,0\leq f(v)\leq 1\)

题目描述

  前面两个操作就是link和cut。

  我们需要在每个点上维护这个函数,但这些都不是多项式函数。我们可以发现\(0\leq v\leq 1\),所以可以暴力维护这些函数在\(x=0\)处的泰勒展开式(就是生成函数)。我维护了前面\(15\)项。

\[\begin{align}
e^x&=\sum_{i=0}^\infty \frac{x^i}{i!}\\
\sin(x)&=\sum_{i=0}^\infty{(-1)}^i\frac{x^{2i+1}}{(2i+1)!}
\end{align}
\]

  每个函数的\(x=av+b\),直接用二项式定理暴力展开就可以了。

  时间复杂度:\(O(len\times m\log n)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<cmath>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void sort(int &a,int &b)
{
if(a>b)
swap(a,b);
}
void open(const char *s)
{
#ifdef DEBUG
char str[100];
sprintf(str,"%s.in",s);
freopen(str,"r",stdin);
sprintf(str,"%s.out",s);
freopen(str,"w",stdout);
#endif
}
const int len=15;
namespace lct
{
double v[100010][16];
double s[100010][16];
int a[100010][2];
int f[100010];
int r[100010];
void cp(int x)
{
memcpy(s[x],v[x],sizeof(double)*(len+1));
}
int root(int x)
{
return !f[x]||(a[f[x]][0]!=x&&a[f[x]][1]!=x);
}
void reverse(int x)
{
swap(a[x][0],a[x][1]);
r[x]^=1;
}
void push(int x)
{
if(r[x])
{
if(a[x][0])
reverse(a[x][0]);
if(a[x][1])
reverse(a[x][1]);
r[x]=0;
}
}
void mt(int x)
{
int i;
int ls=a[x][0];
int rs=a[x][1];
for(i=0;i<=len;i++)
s[x][i]=v[x][i]+s[ls][i]+s[rs][i];
}
void rotate(int x)
{
int p=f[x];
int q=f[p];
int ps=(x==a[p][1]);
int qs=(p==a[q][1]);
int ch=a[x][ps^1];
if(!root(p))
a[q][qs]=x;
a[x][ps^1]=p;
a[p][ps]=ch;
if(ch)
f[ch]=p;
f[p]=x;
f[x]=q;
mt(p);
mt(x);
}
void pushdown(int x)
{
if(!root(x))
pushdown(f[x]);
push(x);
}
void splay(int x)
{
pushdown(x);
while(!root(x))
{
int p=f[x];
if(!root(p))
{
int q=f[p];
if((x==a[p][1])==(p==a[q][1]))
rotate(p);
else
rotate(x);
}
rotate(x);
}
}
void access(int x)
{
int y=x,t=0;
while(x)
{
splay(x);
a[x][1]=t;
mt(x);
t=x;
x=f[x];
}
splay(y);
}
void change(int x)
{
access(x);
reverse(x);
}
void link(int x,int y)
{
change(x);
f[x]=y;
splay(x);
}
void cut(int x,int y)
{
change(x);
access(y);
f[a[y][0]]=0;
a[y][0]=0;
mt(y);
}
int find(int x)
{
access(x);
while(a[x][0])
x=a[x][0];
splay(x);
return x;
}
double query(int x,int y,double v)
{
double res=0;
change(x);
access(y);
int i;
for(i=len;i>=0;i--)
{
res*=v;
res+=s[y][i];
}
return res;
}
}
double c[16][16];
double fac[16];
void init()
{
int i,j;
fac[0]=1;
for(i=1;i<=len;i++)
fac[i]=fac[i-1]*i;
for(i=0;i<=len;i++)
{
c[i][0]=1;
for(j=1;j<=i;j++)
c[i][j]=c[i-1][j-1]+c[i-1][j];
}
}
inline double get(int t,int x)
{
if(t==1)
{
if(x%4==1)
return 1/fac[x];
else if(x%4==3)
return -1/fac[x];
return 0;
}
else if(t==2)
{
return 1/fac[x];
}
else
{
if(x==1)
return 1;
return 0;
}
}
void change(double *s,int t,double a,double b)
{
static double pa[16],pb[16];
int i,j;
for(i=0;i<=len;i++)
s[i]=0;
pa[0]=pb[0]=1;
for(i=1;i<=len;i++)
{
pa[i]=pa[i-1]*a;
pb[i]=pb[i-1]*b;
}
double v;
if(t==1)
{
for(i=1;i<=len;i+=2)
{
v=get(t,i);
for(j=0;j<=i;j++)
//(ax+b)^t=C(t,i)a^ib^(t-i)
s[j]+=v*c[i][j]*pa[j]*pb[i-j];
}
}
else if(t==2)
{
for(i=0;i<=len;i++)
{
v=get(t,i);
for(j=0;j<=i;j++)
//(ax+b)^t=C(t,i)a^ib^(t-i)
s[j]+=v*c[i][j]*pa[j]*pb[i-j];
}
}
else
{
s[0]=b;
s[1]=a;
}
}
int main()
{
open("bzoj5020");
init();
int n,m;
char type[100];
scanf("%d%d%s",&n,&m,type);
double a,b,v;
int x,y,t;
int i;
for(i=1;i<=n;i++)
{
scanf("%d%lf%lf",&t,&a,&b);
change(lct::v[i],t,a,b);
lct::cp(i);
}
for(i=1;i<=m;i++)
{
scanf("%s",type);
if(type[0]=='a')
{
scanf("%d%d",&x,&y);
x++;
y++;
lct::link(x,y);
}
else if(type[0]=='d')
{
scanf("%d%d",&x,&y);
x++;
y++;
lct::cut(x,y);
}
else if(type[0]=='m')
{
scanf("%d%d%lf%lf",&x,&t,&a,&b);
x++;
lct::access(x);
change(lct::v[x],t,a,b);
lct::cp(x);
}
else
{
scanf("%d%d%lf",&x,&y,&v);
x++;
y++;
if(lct::find(x)!=lct::find(y))
{
printf("unreachable\n");
continue;
}
double ans=lct::query(x,y,v);
printf("%.8le\n",ans);
}
}
return 0;
}

【BZOJ5020】【THUWC2017】在美妙的数学王国中畅游 LCT 泰勒展开的更多相关文章

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

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

  2. [THUWC2017]在美妙的数学王国中畅游 LCT+泰勒展开+求导

    p.s. 复合函数求导时千万不能先带值,再求导. 一定要先将符合函数按照求导的规则展开,再带值. 设 $f(x)=g(h(x))$,则对 $f(x)$ 求导: $f'(x)=h'(x)g'(h(x)) ...

  3. 【BZOJ5020】[LOJ2289]【THUWC2017】在美妙的数学王国中畅游 - LCT+泰勒展开

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

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

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

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

    明摆着的LCT,问题在于如何维护答案.首先注意到给出的泰勒展开式,并且所给函数求导非常方便,肯定要用上这玩意.容易想到展开好多次达到精度要求后忽略余项.因为x∈[0,1]而精度又与|x-x0|有关,当 ...

  6. [THUWC2017][bzoj5020] 在美妙的数学王国中畅游 [LCT+泰勒展开]

    题面 LOJ传送门 思路 这里很重要 它提示我们,把给定的三个函数泰勒展开,并用LCT维护每一项泰勒展开式的值,维护十几项就满足了题目的精度要求 我们考虑一个函数在0位置的泰勒展开 $f(x)=\su ...

  7. Luogu4546 THUWC2017 在美妙的数学王国中畅游 LCT、泰勒展开

    传送门 题意:反正就是一堆操作 LCT总是和玄学东西放在一起我们不妨令$x_0=0.5$(其实取什么都是一样的,但是最好取在$[0,1]$的范围内),将其代入给出的式子,我们得到的$f(x)$的式子就 ...

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

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

  9. bzoj5020 & loj2289 [THUWC 2017]在美妙的数学王国中畅游 LCT + 泰勒展开

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5020 https://loj.ac/problem/2289 题解 这个 appear 和 d ...

随机推荐

  1. jQuery 初识 筛选器 属性选择器

    ---------------------------大事使我们惊讶,小事使我们沮丧,久而久之,我们对这二者都会习以为常. 一 jQuery是什么? [1]   jQuery由美国人John Resi ...

  2. 简单的将Excel数据同步到SqlServer数据库中

    1.创建一个WinForm程序,添加一个Button控件 2.Button事件 private void button1_Click(object sender, EventArgs e) { Sys ...

  3. Python-os模块-60

    os 模块: 和操作系统打交道的模块 os模块是与操作系统交互的一个接口 os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirna ...

  4. struts2之配置文件struts.xml详解

    struts配置文件 struts.xml配置参数详解 struts.xml中很大一部分配置默认配置就好了 但是有些还是需要做了解  以便于理解 和修改 <?xml version=" ...

  5. 百度地图开发者API学习笔记一(转载)

    一,实现功能: 在地图上标记点,划线等操作.如下图. 2.代码: <!DOCTYPE html> <html> <head> <meta http-equiv ...

  6. Java 学习使用常见的开源连接池

    目录 连接池介绍 自定义连接池 JDBC Tomcat Pool DBCP(DataBase Connection Pool) 使用配置文件来设置DBCP C3P0 Druid 连接池介绍 在说连接池 ...

  7. centos yum install oracle java

    How to install Java on CentOS 7 | Linuxizehttps://linuxize.com/post/install-java-on-centos-7/ CentOS ...

  8. Git - 常见错误与解决方案

    1.windows使用git时出现:warning: LF will be replaced by CRLF 分析: windows中的换行符为 CRLF, 而在linux下的换行符为LF,所以在执行 ...

  9. Mysql占用CPU过高如何优化?(转)

    原文:http://bbs.landingbj.com/t-0-241441-1.html MySQL处在高负载环境下,磁盘IO读写过多,肯定会占用很多资源,必然CP会U占用过高. 占用CPU过高,可 ...

  10. 关于vagrant一个虚拟机搭建多个项目配置(总结)

    问题1:执行vagrant status命令,报错,没有找到命令,翻译:“vargrant bash命令没有找到.” 解答:因为在/home目录中,所有无法执行该命令,需要切换到外部进行执行 问题2: ...