THUWC 2017在美妙的数学王国中畅游

Posted 租酥雨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了THUWC 2017在美妙的数学王国中畅游相关的知识,希望对你有一定的参考价值。

数学王国里有n座城市,每座城市有三个参数\(f\)\(a\)\(b\),一个智商为\(x\)的人经过一座城市的获益\(f(x)\)
\(f=1\),则\(f(x)=sin(ax+b)\)
\(f=2\),则\(f(x)=e^{ax+b}\)
\(f=3\),则\(f(x)=ax+b\)
会发生如下四种事件:
1、有两个城市之间新建了道路;
2、有两个城市之间的道路被摧毁了;
3、城市i的三个参数被修改了;
4、求智商为x的人从u走到v的获益总和。
保证任何时候图是一个森林。

题解

这是一道数学题

如果每座城市的\(f\)都是\(3\)你会做吗?
很简单,LCT维护一下路径上的\(\sum a,\sum b\)即可。
可见我们维护出来的就是函数的一次项系数和常系数。
所以说,如果我告诉你每座城市都是一个不超过13项的多项式函数,你应该不会还不知道怎么做了吧。
但显然这\(sin(ax+b)\)啊,什么\(e^{ax+b}\)啊,这都是些什么鬼。
但如果我可以把它们展开成多项式呢?
根据泰勒公式,我们有
\[f(x)=\sum_{i=0}^{n} \frac{f^{(i)}(x_0)*(x-x_0)^i}{i!}\]
其中\(f^{(i)}(x)\)表示函数\(f(x)\)\(i\)阶导。
上式是一个近似式,近似度随\(n\)的取值而不断递增。要精确到题目要求的1e-7的话\(n\)只要取12,13就可以了。

数学小课堂——关于指数函数、三角函数、复活(雾)函数的求导

指数函数的求导
\[(a^x)'=a^x*lna\]
(\(lna\)代表取自然对数)。
特殊的,
\[(e^x)'=e^x\]
三角函数的求导
\[(sinx)'=cosx\]
\[(cosx)'=-sinx\]
\[(-sinx)'=-cosx\]
\[(-cosx)'=sinx\]
(所以说是循环四个,周期!)
复合函数
\[[f(g(x))]'=g'(x)*f'(g(x))\]
放到这道题里面去
\[sin'(ax+b)=acos(ax+b)\]
\[sin''(ax+b)=-a^2sin(ax+b)\]
\[sin'''(ax+b)=-a^3cos(ax+b)\]
以此类推
\[(e^{ax+b})^{(n)}=a^ne^{ax+b}\]
一次函数就不说了
然后这题就做完了

code

然而这份代码交到BZOJ上还是T

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 100005;
const int M = 13;
const double e = 2.718281828;
int n,m,fa[N],ls[N],rs[N],rev[N],f[N],Stack[N],top;
double jc[M],sum[M][N],a[N],b[N];
char type[N],s[N];
bool isroot(int x){return ls[fa[x]]!=x&&rs[fa[x]]!=x;}
void pushup(int x)
{
    for (int i=0;i<M;i++)
        sum[i][x]=sum[i][ls[x]]+sum[i][rs[x]];
    if (f[x]==1)
    {
        double val=1;
        for (int i=0;i<M;i++)
        {
            if (i%4==0) sum[i][x]+=sin(b[x])*val;
            if (i%4==1) sum[i][x]+=cos(b[x])*val;
            if (i%4==2) sum[i][x]+=-sin(b[x])*val;
            if (i%4==3) sum[i][x]+=-cos(b[x])*val;
            val*=a[x];
        }
    }
    if (f[x]==2)
    {
        double val=pow(e,b[x]);sum[0][x]+=val;
        for (int i=1;i<M;i++)
            val*=a[x],sum[i][x]+=val;
    }
    if (f[x]==3)
        sum[0][x]+=b[x],sum[1][x]+=a[x];
}
void pushdown(int x){if (!rev[x]) return;swap(ls[x],rs[x]);rev[ls[x]]^=1;rev[rs[x]]^=1;rev[x]=0;}
void R_rotate(int x)
{
    int y=fa[x],z=fa[y];
    ls[y]=rs[x];
    if (rs[x]) fa[rs[x]]=y;
    fa[x]=z;
    if (!isroot(y)) if (y==ls[z]) ls[z]=x;else rs[z]=x;
    rs[x]=y;fa[y]=x;
    pushup(y);
}
void L_rotate(int x)
{
    int y=fa[x],z=fa[y];
    rs[y]=ls[x];
    if (ls[x]) fa[ls[x]]=y;
    fa[x]=z;
    if (!isroot(y)) if (y==ls[z]) ls[z]=x;else rs[z]=x;
    ls[x]=y;fa[y]=x;
    pushup(y);
}
void splay(int x)
{
    Stack[++top]=x;
    for (int i=x;!isroot(i);i=fa[i])
        Stack[++top]=fa[i];
    while (top) pushdown(Stack[top--]);
    while (!isroot(x))
    {
        int y=fa[x],z=fa[y];
        if (isroot(y))
            if (x==ls[y]) R_rotate(x);
            else L_rotate(x);
        else
            if (y==ls[z])
                if (x==ls[y]) R_rotate(y),R_rotate(x);
                else L_rotate(x),R_rotate(x);
            else
                if (x==ls[y]) R_rotate(x),L_rotate(x);
                else L_rotate(y),L_rotate(x);
    }
    pushup(x);
}
void access(int x){for (int y=0;x;y=x,x=fa[x]) splay(x),rs[x]=y,pushup(x);}
void makeroot(int x){access(x);splay(x);rev[x]^=1;}
int findroot(int x){access(x);splay(x);while (ls[x]) x=ls[x];return x;}
void split(int x,int y){makeroot(x);access(y);splay(y);}
void link(int x,int y){makeroot(x);fa[x]=y;}
void cut(int x,int y){split(x,y);ls[y]=fa[x]=0;}
int main()
{
    freopen("math.in","r",stdin);
    freopen("math.out","w",stdout);
    jc[0]=1;
    for (int i=1;i<M;i++)
        jc[i]=jc[i-1]*i;
    scanf("%d %d %s",&n,&m,type);
    for (int i=1;i<=n;i++)
        scanf("%d %lf %lf",&f[i],&a[i],&b[i]);
    while (m--)
    {
        int u,v,ff;
        double aa,bb,x,IQ,ans;
        scanf("%s",s);
        if (s[0]=='a')
        {
            scanf("%d %d",&u,&v);
            u++;v++;
            link(u,v);
        }
        if (s[0]=='d')
        {
            scanf("%d %d",&u,&v);
            u++;v++;
            cut(u,v);
        }
        if (s[0]=='m')
        {
            scanf("%d %d %lf %lf",&u,&ff,&aa,&bb);
            u++;
            makeroot(u);
            f[u]=ff;a[u]=aa;b[u]=bb;
            pushup(u);
        }
        if (s[0]=='t')
        {
            scanf("%d %d %lf",&u,&v,&IQ);x=1;
            u++;v++;
            if (findroot(u)^findroot(v)) {puts("unreachable");continue;}
            split(u,v);
            ans=0;
            for (int i=0;i<M;i++)
                ans+=sum[i][v]*x/jc[i],x*=IQ;
            printf("%.8e\n",ans);
        }
    }
    return 0;
}

以上是关于THUWC 2017在美妙的数学王国中畅游的主要内容,如果未能解决你的问题,请参考以下文章

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

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

THUWC 2017在美妙的数学王国中畅游

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

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

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