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


    题目描述

    题解:

    这是一道数学题。

    看一眼会发现暴力跑链会超时。

    所以我们需要一些神奇的东西。

    泰勒展开:

    最后那个东西可以当作无穷小。

    所以我们可以提一下:

    所以我们用LCT维护树链的$f(x0)$前k阶导数就好了。

    还有,这道题卡精,一定要将单点值放在函数里面。

    代码:

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 100050
    #define db double
    inline int rd()
    {
        int f=1,c=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
        return f*c;
    }
    int n,m,f[N];
    char typ[10];
    db dv[16],a[N],b[N];
    /*
    void F1(int x)
    {
        if(!x)return ;
        db A = 1.0;
        db sn = sin(b),cs = cos(b);
        for(int i=0;i<=15;i++,A*=a)
        {
            if(i%4==0)f[x][i] = A*sn;
            else if(i%4==1)f[x][i] = A*cs;
            else if(i%4==2)f[x][i] = -A*sn;
            else f[x][i] = -A*cs;
        }
    }
    void F2(int x)
    {
        if(!x)return ;
        db A = 1.0,ex = exp(b);
        for(int i=0;i<=15;i++,A*=a)
            f[x][i] = A*ex;
    }
    void F3(int x)
    {
        if(!x)return ;
        f[x][0] = b;
        f[x][1] = a;
    }
    */
    struct LCT
    {
        int fa[N],ch[N][2];
        db v[N][16];
        bool res[N];
        bool isroot(int x)
        {
            return x!=ch[fa[x]][0]&&x!=ch[fa[x]][1];
        }
        void update(int u)
        {
            for(int i=0;i<=15;i++)
                v[u][i] = v[ch[u][0]][i] + v[ch[u][1]][i];
            if(f[u]==1)
            {
                db A = 1.0;
                db sn = sin(b[u]),cs = cos(b[u]);
                for(int i=0;i<=15;i++,A*=a[u])
                {
                    if(i%4==0)v[u][i] += A*sn;
                    else if(i%4==1)v[u][i] += A*cs;
                    else if(i%4==2)v[u][i] -= A*sn;
                    else v[u][i] -= A*cs;
                }
            }else if(f[u]==2)
            {
                db A = 1.0,ex = exp(b[u]);
                for(int i=0;i<=15;i++,A*=a[u])
                    v[u][i] += A*ex;
            }else
            {
                v[u][0]+=b[u];
                v[u][1]+=a[u];
            }
        }
        void reser(int u)
        {
            res[u]^=1;
            swap(ch[u][0],ch[u][1]);
        }
        void pushdown(int u)
        {
            if(res[u])
            {
                reser(ch[u][0]);
                reser(ch[u][1]);
                res[u] = 0;
            }
        }
        int st[N],tl;
        void down(int x)
        {
            st[tl=1]=x;
            while(!isroot(x))x=fa[x],st[++tl] = x;
            while(tl)pushdown(st[tl]),tl--;
        }
        void rotate(int x)
        {
            int y = fa[x],z = fa[y],k = (ch[y][1]==x);
            if(!isroot(y))ch[z][ch[z][1]==y] = x;
            fa[x] = z;
            ch[y][k] = ch[x][!k] , fa[ch[x][!k]] = y;
            ch[x][!k] = y,fa[y] = x;
            update(y),update(x);
        }
        void splay(int x)
        {
            down(x);
            while(!isroot(x))
            {
                int y = fa[x],z = fa[y];
                if(!isroot(y))
                    (ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y);
                rotate(x);
            }
        }
        void access(int x)
        {
            int y = 0;
            while(x)
            {
                splay(x);
                ch[x][1] = y;
                update(x);
                y = x,x = fa[x];
            }
        }
        void mtr(int x)
        {
            access(x);
            splay(x);
            reser(x);
        }
        void link(int x,int y)
        {
            mtr(x);
            fa[x] = y;
        }
        void cut(int x,int y)
        {
            mtr(x);
            access(y);
            splay(y);
            ch[y][0] = fa[x] = 0;
            update(y);
        }
        void Magic(int x)
        {
            splay(x);
            update(x);
        }
        int findrt(int x)
        {
            access(x);
            splay(x);
            while(ch[x][0])x=ch[x][0];
            return x;
        }
        void query(db k,int x,int y)
        {
            mtr(x);
            access(y);
            splay(y);
            db ans = 0.0,D = k,A = 1.0;
            for(int i=0;i<=15;i++,A*=D)
            {
                ans += A*v[y][i]/dv[i];
            }
            printf("%.8e
    ",ans);
        }
    }tr;
    int main()
    {
        n = rd(),m = rd();
        scanf("%s",typ+1);
        dv[0]=1.0;
        for(int i=1;i<=15;i++)
            dv[i] = dv[i-1]*(db)i;
        for(int i=1;i<=n;i++)
        {
            f[i] = rd();scanf("%lf%lf",&a[i],&b[i]);
        }
        for(int x,y,i=1;i<=m;i++)
        {
            scanf("%s",typ+1);
            x = rd(),y = rd();
            if(typ[1]=='a')tr.link(x+1,y+1);
            if(typ[1]=='d')tr.cut(x+1,y+1);
            if(typ[1]=='m')
            {
                f[x+1]=y;
                scanf("%lf%lf",&a[x+1],&b[x+1]);
                tr.Magic(x+1);
            }
            if(typ[1]=='t')
            {
                scanf("%lf",&a[0]);
                if(tr.findrt(x+1)!=tr.findrt(y+1))
                {
                    puts("unreachable");
                }else tr.query(a[0],x+1,y+1);
            }
        }
        return 0;
    }
  • 相关阅读:
    C++读写文件并排序
    我的vim配置---jeffy-vim-v2.2.tar
    vim 代码注释插件
    我的vim配置---jeffy-vim-v2.1.tar
    linux中screen命令的用法
    Install and Enable Telnet server in Ubuntu Linux
    Telnet环境变量
    Telnet窗口尺寸选项
    TELNET终端类型选项
    Telnet技术白皮书
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10168043.html
Copyright © 2020-2023  润新知