bzoj5020 在美妙的数学王国中畅游【LCT+泰勒展开】

解题思路:

题目后貌似还有一段提示:
这里写图片描述
但考试的时候完全看不懂它给的泰勒展开式,只打了可以暴力走和 x=1 的部分,就是LCT维护路径和。

考试后看了题解,原来它的意思就是取 x0=0 f(x) 可以化成多项式形式,每项系数就是 fi(0)i!n=11 精度就够了,然后Splay维护每一项系数的和,询问时每项乘以 xi 就行了。

对导数不熟悉的可看:http://blog.csdn.net/cdsszjj/article/details/74600569
有常见导数大概的简介。

再说一下每个函数的泰勒展开(取 x0=0 ):
(1)sin(ax+b)=sin(b)+acos(b)1!xa2sin(b)2!x2a3cos(b)3!x3+a4sin(b)4!x4+
(2)eax+b=eb+aeb1!x+a2eb2!x2+a3eb3!x3+
(3)ax+b=ax+b (要是只有这个我考试还是会做的……呵呵)

ps:c++库中有函数exp(b)可以直接得到 eb 的值,我考试时竟然二分去找了……

#include<bits/stdc++.h>
#define ll long long
using namespace std;

int getint()
{
    int i=0,f=1;char c;
    for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
    if(c=='-')f=-1;
    for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
    return i*f;
}

const int N=100005,lim=11;
int n,m;
int top,stk[N];
int tot,son[N][2],fa[N],rev[N];
double a[N][lim],sum[N][lim];
char s[20];
ll fac[lim];

inline void update(int x)
{
    for(int i=0;i<lim;i++)
        sum[x][i]=sum[son[x][0]][i]+sum[son[x][1]][i]+a[x][i];
}

inline int which(int x)
{
    return son[fa[x]][1]==x;
}

inline bool rt(int x)
{
    return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;
}

inline void pushdown(int x)
{
    swap(son[x][0],son[x][1]);
    rev[x]=0;
    if(son[x][0])rev[son[x][0]]^=1;
    if(son[x][1])rev[son[x][1]]^=1;
}

inline void Rotate(int x)
{
    int y=fa[x],z=fa[y],t=which(x);
    if(!rt(y))son[z][which(y)]=x;
    fa[y]=x,fa[x]=z;
    son[y][t]=son[x][t^1],son[x][t^1]=y;
    if(son[y][t])fa[son[y][t]]=y;
    update(y),update(x);
}

inline void Splay(int x)
{
    stk[top=1]=x;
    for(int i=x;!rt(i);i=fa[i])stk[++top]=fa[i];
    for(int i=top;i;i--)if(rev[stk[i]])pushdown(stk[i]);
    while(!rt(x))
    {
        if(!rt(fa[x]))
            which(x)==which(fa[x])?Rotate(fa[x]):Rotate(x);
        Rotate(x);
    }
}

inline void Access(int x)
{
    for(int y=0;x;y=x,x=fa[x])
    {
        Splay(x),son[x][1]=y;
        if(y)fa[y]=x;
        update(x);
    }
}

inline int Findroot(int x)
{
    Access(x),Splay(x);
    if(rev[x])pushdown(x);
    while(son[x][0])
    {
        x=son[x][0];
        if(rev[x])pushdown(x);
    }
    return x;
}

inline void Makeroot(int x)
{
    Access(x),Splay(x);
    rev[x]^=1;
}

inline void Link(int x,int y)
{
    Makeroot(x),fa[x]=y;
}

inline void Cut(int x,int y)
{
    Makeroot(x),Access(y),Splay(y);
    fa[x]=son[y][0]=0;
}

inline double query(int u,int v,double x)
{
    Makeroot(u),Access(v),Splay(v);
    double tmp=1,res=0;
    for(int i=0;i<lim;i++)
        res+=tmp*sum[v][i],tmp*=x;
    return res;
}

inline void trans(int op,double *a,double A,double B)
{
    if(op==1)
    {
        double Sin=sin(B),Cos=cos(B),tmp=1;int f;
        for(int i=0;i<lim;i++)
        {
            f=((i>>1)&1)?-1:1;
            a[i]=f*tmp*(i&1?Cos:Sin)/fac[i];
            tmp*=A;
        }
    }
    else if(op==2)
    {
        double eb=exp(B),tmp=1;
        for(int i=0;i<lim;i++)
        {
            a[i]=tmp*eb/fac[i];
            tmp*=A;
        }
    }
    else
    {
        a[0]=B,a[1]=A;
        for(int i=2;i<lim;i++)a[i]=0;
    }
}

int main()
{
    //freopen("lx.in","r",stdin);
    //freopen("lx.out","w",stdout);
    fac[0]=1;
    for(int i=1;i<lim;i++)fac[i]=1ll*fac[i-1]*i;
    int op,u,v;double A,B,x;
    n=getint(),m=getint();scanf("%s",s);
    for(int i=1;i<=n;i++)
    {
        op=getint();scanf("%lf%lf",&A,&B);
        trans(op,a[i],A,B);
    }
    while(m--)
    {
        scanf("%s",s);u=getint()+1,v=getint()+1;
        if(s[0]=='a')Link(u,v);
        else if(s[0]=='d')Cut(u,v);
        else if(s[0]=='t')
        {
            scanf("%lf",&x);
            if(Findroot(u)!=Findroot(v))puts("unreachable");
            else printf("%.9f\n",query(u,v,x));
        }
        else
        {
            scanf("%lf%lf",&A,&B);
            Makeroot(u);
            trans(--v,a[u],A,B);
            update(u);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值