"LOJ 2289" and "THUWC 2017" Swim in the Wonderful Realm of Mathematics - LCT & Taylor Expansion

Topic meaning:

  portal

  Given a dynamic tree, a function is maintained on each node as $f(x)=sin(ax+b)$, $f(x)=e^{ax+b}$, $f(x)=ax+ one of b$.

  Supports deleting edges and connecting edges, and modifying the operation of functions on nodes.

  Each query takes the sum of the values ​​of $x$ into all functions on the path from $u$ to $v$.

answer:

  gives a Taylor formula

  (Paste from Baidu)

  But...if you know the derivative, you should know it...if you don't know the derivative, it will be given for nothing...I don't know what the person who asked the question thinks...

  Speaking of which, isn't it bad to expand + derivative directly to McLaughlin...

  Because the derivative of $f(x)=e^x$, $f'(x)=e^x$, has its McLaughlin expansion when taking $x_0=0$:

  $f(x)=e^x=\sum_{i=0}^{\infty}\frac{x^i}{i!}$

  The derivative of $sin(x)$ is $cos(x)$, and the derivative of $cos(x)$ is $-sin(x)$. So when $x_0=0$, it is found that $f(x)$ odd $i$ order derivative is $(-1)^{\frac{i-1}{2}}$, and even order derivative is 0. Has its McLaughlin unfold:

  $f(x)=\sum_{i=0}^{\infty}\ (-1)^i \frac{ x^{2i+i} }{(2i+i)!}$

  Considering that the data range of this question does not need to be expanded too much, about 20 items are enough.

  Then bring in the given parameter $ax+b$ to get a polynomial of length 20 about $x$, we can maintain the sum of the coefficients on the chain when we LCT.

Code:

#include "bits/stdc++.h"

inline int read (){
    int s=0,k=1;char ch=getchar();
    while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
    while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
    return s*k;
}

#define double long double

using namespace std;

const int N=1e5+10;

int C[20][20];
long long fac[20];

inline void init() {
    register int i,j;
    for (C[0][0]=i=1;i<20;++i)
        for (C[i][0]=j=1;j<=i;++j)
            C[i][j]=C[i-1][j]+C[i-1][j-1];
    for (fac[0]=i=1;i<20;++i)
        fac [i] = fac [i-1] * i;
}

namespace LCT {
    #define rev(t) (t?t->rev^=1:0)
    #define is_root(t) (!t->fa||(t->fa->son[0]!=t&&t->fa->son[1]!=t))
    #define son(t) (t->fa->son[1]==t)
    #define size(t,s) (t?t->size[s]:0)
    struct node {
        node () {fa=son[0]=son[1]=NULL,rev=0,memset(self,0,sizeof self),memset(size,0,sizeof size);}
        node * fa, * son [2];
        double self[20],size[20];
        int rev;
        inline void pushdown()  {
            if (!rev) return ;
            swap(son[0],son[1]);
            rev(son[0]),rev(son[1]);
            rev=0;
        }
        inline void update() {
            for (int i=0;i<20;++i)
                size[i]=size(son[0],i)+size(son[1],i)+self[i];
        }
        inline double ans(double x) {
            double ans=0,now=1.0;
            for (int i=0;i<20;++i,now*=x)
                ans+=now*size[i];
            return ans;
        }
        inline void calc(int type,double a[],double b[]) {
            memset(self,0,sizeof self);
            if (type==1) {

                for (int i=0;i<20;++i)  if (i%2)
                    for (int j=0;j<=i;++j) {
                        self[j]+=((((i-1)/2)&1)?-1:1)*a[j]*b[i-j]*C[i][j]/fac[i];     
                    }           
            }else if(type==2) {
                for (int i=0;i<20;++i)
                    for (int j=0;j<=i;++j)
                        self[j]+=a[j]*b[i-j]*C[i][j]/fac[i];
            }else self[0]=b[1],self[1]=a[1];
        }

    }tree[N],*tmp[N];
    
    inline void rotate(node *p){
        int a=son(p)^1;node *f=p->fa;
        f->son[a^1]=p->son[a];
        if (p->son[a]) p->son[a]->fa=f;
        p->fa=f->fa;
        if (!is_root(f)) f->fa->son[son(f)]=p;
        f->fa=p,p->son[a]=f,f->update(),p->update();
    }
    
    inline void update(node *p){
        if (!is_root(p)) update(p->fa);
        p->pushdown();
    }
    
    inline void splay(node *p){
        register int pos=0;
        for(node *t=p;;t=t->fa){
            tmp[++pos]=t;
            if(is_root(t)) break;
        }
        for(;pos;--pos) tmp[pos]->pushdown();
        for(;!is_root(p);rotate(p))
            if(!is_root(p->fa)) rotate(son(p)==son(p->fa)?p->fa:p);
    }
    
    inline void access(node *p){
        for(node *pre=NULL;p;pre=p,p=p->fa)
            splay(p),p->son[1]=pre,p->update();
    }
    
    inline void make_root(node *x) {
        access(x),splay(x),x->rev^=1;
    }
    
    inline void link(node *x,node *y) {
        make_root(x);access(y),splay(y),x->fa=y;
        y->update();
    }
    
    inline void cut(node *x,node *y){
        make_root(x),access(y),splay(y);
        x->fa=y->son[0]=NULL;y->update();
    }
    
    inline double query(node *x,node *y,double xx){
        make_root(x),access(y),splay(y);
        return y->ans(xx);
    }
    
    inline int finds(node *x) {
        access(x),splay(x);
        while (x->son[0]) x=x->son[0],x->pushdown();
        return x-tree;
    }
}

int n,m;
double a[20],b[20];

int main (int argc, char const* argv[]){
    //freopen("2289.in","r",stdin);
    init();    
    char opt[20];
    n=read(),m=read(),scanf("%s",opt);
    int type;
    a[0]=b[0]=1.0;
    using namespace LCT;
    for (int i=1;i<=n;++i)  {
        type=read();
        scanf("%Lf%Lf",a+1,b+1);
        for (int j=2;j<20;++j)
            a[j]=a[j-1]*a[1],
            b[j]=b[j-1]*b[1];
        tree[i].calc(type,a,b);   
    }

    int u, v, c;
    double x;
    while (m--) {
        scanf("%s",opt);
        if (opt[0]=='a') {
            u=read()+1,v=read()+1;
            link(&tree[u],&tree[v]);
        }else if (opt[0]=='d') {
            u=read()+1,v=read()+1;
            cut(&tree[u],&tree[v]);
        }
        else if (opt[0]=='m') {
            c=read()+1,type=read();
            scanf("%Lf%Lf",a+1,b+1);
            for (int j=2;j<20;++j)
                a[j]=a[j-1]*a[1],
                b[j]=b[j-1]*b[1];
            make_root(&tree[c]);
            tree[c].calc(type,a,b);
            tree[c].update();
        }
        else {
            u=read()+1,v=read()+1;
            scanf("%Lf",&x);
            if (finds(&tree[u])^finds(&tree[v]))   {
                puts("unreachable");
            }
            else {
                printf("%.8Le\n",query(&tree[u],&tree[v],x));
            }
        }
    }
    return 0;
}

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325167240&siteId=291194637