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


    题意

    题意奇奇怪怪,这里就不写了。

    ( exttt{Data Range:}1leq nleq 10^5,1leq mleq 2 imes 10^5)

    题解

    为什么你们都是卡在数学方面,难道只有我卡在不晓得怎么维护上面吗

    看到下面的题解通篇的泰勒展开,我决定写一篇从 ( exttt{EGF}) 上说明的题解,而且公式也比下面的清晰的多。

    首先我们做个热身,先来看 (e^x,sin x,cos x) 对应的 ( exttt{EGF})

    [e^x=sumlimits_{i=0}^{infty}frac{x^i}{i!} ]

    [sin x=sumlimits_{i=0}^{infty}frac{(-1)^ix^{2i+1}}{(2i+1)!} ]

    [cos x=sumlimits_{i=0}^{infty}frac{(-1)^ix^{2i}}{(2i)!} ]

    接下来我们用 (ax) 替换 (x) 得到:

    [e^{ax}=sumlimits_{i=0}^{infty}frac{a^ix^i}{i!} ]

    [sin (ax)=sumlimits_{i=0}^{infty}frac{(-1)^ia^{2i+1}x^{2i+1}}{(2i+1)!} ]

    [cos (ax)=sumlimits_{i=0}^{infty}frac{(-1)^ia^{2i}x^{2i}}{(2i)!} ]

    如果写的更直观一点呢?

    [e^{ax}=1+ax+frac{a^2x^2}{2!}+frac{a^3x^3}{3!}+cdots ]

    [sin(ax)=ax-frac{a^3x^3}{3!}+frac{a^5x^5}{5!}-frac{a^7x^7}{7!}+cdots ]

    [cos(ax)=1-frac{a^2x^2}{2!}+frac{a^4x^4}{4!}-frac{a^6x^6}{6!}+cdots ]

    接下来就是正题了。

    考虑到 (e^{ax+b}=e^{ax}cdot e^{b}),而 (b) 是给定常数,所以

    [e^{ax+b}=e^b(1+ax+frac{a^2x^2}{2!}+frac{a^3x^3}{3!}+cdots)=sumlimits_{i=0}^{infty}frac{e^ba^ix^i}{i!} ]

    然后根据常见的三角恒等变换公式,我们有

    [sin(ax+b)=sin(ax)cos b+cos(ax)sin b ]

    (b) 是给定的常数,所以

    [sin(ax+b)=cos b(ax-frac{a^3x^3}{3!}+frac{a^5x^5}{5!}-frac{a^7x^7}{7!}+cdots)+sin b(1-frac{a^2x^2}{2!}+frac{a^4x^4}{4!}-frac{a^6x^6}{6!}+cdots) ]

    [sin(ax+b)=sumlimits_{i=0}^{infty}frac{cos b(-1)^ia^{2i+1}x^{2i+1}}{(2i+1)!}+frac{sin b(-1)^ia^{2i}x^{2i}}{(2i)!} ]

    然后维护一下这些 ( exttt{EGF}) 就可以直接做了。我的代码维护到 (15) 项,所以比较慢,但还是能过。(至少不用像鰰一样预处理组合数)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef int ll;
    typedef long long int li;
    typedef long double db;
    const ll MAXN=2e5+51;
    struct Polynomial{
        db cof[16];
        Polynomial()
        {
            memset(cof,0,sizeof(cof));
        }
        inline Polynomial operator +(const Polynomial &rhs)const
        {
            Polynomial res;
            for(register int i=0;i<16;i++)
            {
                res.cof[i]=cof[i]+rhs.cof[i];
            }
            return res;
        }
        inline db eval(db x)
        {
            db res=0,cur=1;
            for(register int i=0;i<16;i++)
            {
                res+=cof[i]*cur,cur*=x;
            }
            return res;
        }
        inline void op()
        {
            for(register int i=0;i<16;i++)
            {
                printf("%.8Lf
    ",cof[i]);
            }
        }
    };
    ll n,m,x,y,typ;
    db u,v;
    string type,op;
    inline ll read()
    {
        register ll num=0,neg=1;
        register char ch=getchar();
        while(!isdigit(ch)&&ch!='-')
        {
            ch=getchar();
        }
        if(ch=='-')
        {
            neg=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            num=(num<<3)+(num<<1)+(ch-'0');
            ch=getchar();
        }
        return num*neg;
    }
    namespace LCT{
        struct Node{
            ll fa,rv,sz;
            Polynomial poly,sum;
            ll ch[2];
        };
        struct LinkCutTree{
            Node nd[MAXN];
            ll st[MAXN];
            #define ls nd[x].ch[0]
            #define rs nd[x].ch[1]
            inline bool nroot(ll x)
            {
                return nd[nd[x].fa].ch[0]==x||nd[nd[x].fa].ch[1]==x;
            }
            inline void update(ll x)
            {
                nd[x].sum=nd[ls].sum+nd[rs].sum+nd[x].poly;
            }
            inline void reverse(ll x)
            {
                swap(ls,rs),nd[x].rv^=1;
            }
            inline void spread(ll x)
            {
                if(nd[x].rv)
                {
                    ls?reverse(ls):(void)(1),rs?reverse(rs):(void)(1);
                    nd[x].rv=0;
                }
            }
            inline void rotate(ll x)
            {
                ll fa=nd[x].fa,gfa=nd[fa].fa;
                ll dir=nd[fa].ch[1]==x,son=nd[x].ch[!dir];
                if(nroot(fa))
                {
                    nd[gfa].ch[nd[gfa].ch[1]==fa]=x;
                }
                nd[x].ch[!dir]=fa,nd[fa].ch[dir]=son;
                if(son)
                {
                    nd[son].fa=fa;
                }
                nd[fa].fa=x,nd[x].fa=gfa,update(fa);
            }
            inline void splay(ll x)
            {
                ll fa=x,gfa,cur=0;
                st[++cur]=fa;
                while(nroot(fa))
                {
                    st[++cur]=fa=nd[fa].fa;
                }
                while(cur)
                {
                    spread(st[cur--]);
                }
                while(nroot(x))
                {
                    fa=nd[x].fa,gfa=nd[fa].fa;
                    if(nroot(fa))
                    {
                        rotate((nd[fa].ch[0]==x)^(nd[gfa].ch[0]==fa)?x:fa);
                    }
                    rotate(x);
                }
                update(x);
            }
            inline void access(ll x)
            {
                for(register int i=0;x;x=nd[i=x].fa)
                {
                    splay(x),rs=i,update(x);
                }
            }
            inline void makeRoot(ll x)
            {
                access(x),splay(x),reverse(x);
            }
            inline ll findRoot(ll x)
            {
                access(x),splay(x);
                while(ls)
                {
                    spread(x),x=ls;
                }
                return x;
            }
            inline void split(ll x,ll y)
            {
                makeRoot(x),access(y),splay(y);
            }
            inline void link(ll x,ll y)
            {
                makeRoot(x);
                if(findRoot(y)!=x)
                {
                    nd[x].fa=y;
                }
            }
            inline void cut(ll x,ll y)
            {
                makeRoot(x);
                if(findRoot(y)==x&&nd[x].fa==y&&!rs)
                {
                    nd[x].fa=nd[y].ch[0]=0,update(y);
                }
            }
            #undef ls
            #undef rs
        };
    }
    LCT::LinkCutTree lct;
    inline Polynomial sin(db u,db v)
    {
        Polynomial res;
        db sinv=sin(v),cosv=cos(v),pw=1,fact=1;
        for(register int i=0;i<16;i++)
        {
            res.cof[i]=(i&2?-1:1)*(i&1?cosv:sinv)*pw*fact,pw*=u,fact/=(1.0*(i+1));
        }
        return res;
    }
    inline Polynomial exp(db u,db v)
    {
        Polynomial res;
        db expv=exp(v),pw=1,fact=1;
        for(register int i=0;i<16;i++)
        {
            res.cof[i]=expv*pw*fact,pw*=u,fact/=1.0*(i+1);
        }
        return res;
    }
    inline Polynomial linear(db u,db v)
    {
        Polynomial res;
        res.cof[0]=v,res.cof[1]=u;
        return res;
    }
    int main()
    {
        n=read(),m=read(),cin>>type;
        for(register int i=1;i<=n;i++)
        {
            typ=read(),scanf("%Lf%Lf",&u,&v);
            lct.nd[i].poly=typ==1?sin(u,v):typ==2?exp(u,v):linear(u,v);
        }
        for(register int i=0;i<m;i++)
        {
            cin>>op;
            if(op=="appear")
            {
                x=read()+1,y=read()+1,lct.link(x,y);
            }
            if(op=="disappear")
            {
                x=read()+1,y=read()+1,lct.cut(x,y);
            }
            if(op=="magic")
            {
                x=read()+1,typ=read(),scanf("%Lf%Lf",&u,&v);
                lct.splay(x);
                lct.nd[x].poly=typ==1?sin(u,v):typ==2?exp(u,v):linear(u,v);
            }
            if(op=="travel")
            {
                x=read()+1,y=read()+1,scanf("%Lf",&u);
                if(lct.findRoot(x)!=lct.findRoot(y))
                {
                    puts("unreachable");
                    continue;
                }
                lct.split(x,y),printf("%.12Lf
    ",lct.nd[y].sum.eval(u));
            }
        }
    }
    
  • 相关阅读:
    MATLAB 编程风格指南及注意事项
    Redis笔记
    HDU-5706
    【sqli-labs】 less4 GET
    【sqli-labs】 less3 GET
    【sqli-labs】 less2 GET
    【sqli-labs】 less1 GET
    Ubuntu14.04环境下java web运行环境搭建
    Android进度条控件ProgressBar使用
    Android中DatePicker与TimePicker用法讲解(包括DatePickerDialog与TimePickerDialog)
  • 原文地址:https://www.cnblogs.com/Karry5307/p/13067069.html
Copyright © 2020-2023  润新知