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

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

e和sin信息不能直接合并

泰勒展开,大于21次太小,认为是0,保留前21次多项式即可

然后就把e,sin ,kx+b都变成多项式了,pushup合并

上LCT

// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define ld double
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
    char ch;x=0;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}

namespace Miracle{
const int N=1e5+5;
const int K=22;
int n,m;
struct Poly{
    ld a[K];
    Poly(){memset(a,0,sizeof a);}
    il ld &operator[](const int &x){return a[x];}
    il const ld &operator[](const int &x) const {return a[x];}
    Poly friend operator +(const Poly &a,const Poly &b){
        Poly c;
        for(reg i=0;i<K;++i){
            c.a[i]=a.a[i]+b.a[i];
        }
        return c;
    }
    ld calc(ld x){
        ld tmp=1,ret=0;
        for(reg i=0;i<K;++i){
            ret=ret+a[i]*tmp;
            tmp=tmp*x;    
        }
        return ret;
    }
};
int C[30][30];
ld jie[K],ma[K],mb[K]; 
Poly exp(double a,double b){
    Poly ret;
    ma[0]=1;mb[0]=1;
    for(reg i=1;i<K;++i){
        ma[i]=ma[i-1]*a;
        mb[i]=mb[i-1]*b;
    }
    for(reg i=0;i<K;++i){
        for(reg j=0;j<=i;++j){
            ret.a[j]+=C[i][j]*ma[j]*mb[i-j]*jie[i];
        }
    }
    return ret;
}
Poly sin(double a,double b){
    Poly ret;
    ma[0]=1;mb[0]=1;
    for(reg i=1;i<K;++i){
        ma[i]=ma[i-1]*a;
        mb[i]=mb[i-1]*b;
    }
    for(reg i=1;i<K;i+=2){
        for(reg j=0;j<=i;++j){
            if(((i-1)/2)&1){
                ret.a[j]-=C[i][j]*ma[j]*mb[i-j]*jie[i];
            }else{
                ret.a[j]+=C[i][j]*ma[j]*mb[i-j]*jie[i];
            }
        }
    }    
    return ret;
}
Poly init(int typ,double a,double b){
    if(typ==1) return sin(a,b);
    if(typ==2) return exp(a,b);
    Poly ret;
    ret.a[1]=a;
    ret.a[0]=b;
    return ret;
}
struct node{
    int ch[2],fa;
    int rev;
    Poly f,sum;
}t[N];
#define ls t[x].ch[0]
#define rs t[x].ch[1]
void pushup(int x){
    if(!x) return; 
    t[x].sum=t[ls].sum+t[rs].sum+t[x].f;
}
bool nrt(int x){
    return t[t[x].fa].ch[0]==x||t[t[x].fa].ch[1]==x;
}
void rev(int x){
    t[x].rev^=1;
    swap(ls,rs);
}
void pushdown(int x){
    if(t[x].rev){
        rev(ls);rev(rs);
        t[x].rev=0;
    }
}
void rotate(int x){
    int y=t[x].fa,d=t[y].ch[1]==x;
    t[t[y].ch[d]=t[x].ch[!d]].fa=y;
    if(nrt(y)) t[t[x].fa=t[y].fa].ch[t[t[y].fa].ch[1]==y]=x;
    else t[x].fa=t[y].fa;
    t[t[x].ch[!d]=y].fa=x;
    pushup(y);
}
int sta[N];
void splay(int x){
    int y=x,z=0;
    sta[++z]=x;
    while(nrt(y)) y=t[y].fa,sta[++z]=y;
    while(z) pushdown(sta[z--]);
    while(nrt(x)){
        y=t[x].fa,z=t[y].fa;
        if(nrt(y)){
            rotate((t[y].ch[0]==x)==(t[z].ch[0]==y)?y:x);
        }
        rotate(x);
    }
    pushup(x);
}
void access(int x){
    for(reg y=0;x;y=x,x=t[x].fa){
        splay(x);t[x].ch[1]=y;pushup(x);
    }    
}
void makert(int x){
    access(x);splay(x);rev(x);
}
void link(int x,int y){
    makert(x);t[x].fa=y;
}
void split(int x,int y){
    makert(x);access(y);splay(y);
}
void cut(int x,int y){
    split(x,y);
    t[y].ch[0]=t[x].fa=0;
    pushup(y);
}
int findrt(int x){
    access(x);splay(x);
    while(ls) x=ls;
    splay(x);
    return x;
}
ld query(int x,int y,ld v){
    split(x,y);
    return t[y].sum.calc(v);
}
char s[233];
int main(){
    char haha[233];
    rd(n);rd(m);scanf("%s",haha+1);
    
    int typ;
    ld a,b;
    int x,y;
    C[0][0]=1;
    for(reg i=1;i<=K;++i){
        C[i][0]=1;
        for(reg j=1;j<=K;++j){
            C[i][j]=C[i-1][j]+C[i-1][j-1];
        }
    }
    jie[0]=jie[1]=1;
    for(reg i=2;i<=K;++i){
        jie[i]=jie[i-1]/i;
    }
    for(reg i=1;i<=n;++i){
        rd(typ);scanf("%lf%lf",&a,&b);
        t[i].f=init(typ,a,b);
        pushup(i);
    }
    while(m--){
        scanf("%s",s+1);
        if(s[1]=='a'){
            rd(x);rd(y);
            ++x;++y;
            link(x,y);
        }else if(s[1]=='d'){
            rd(x);rd(y);
            ++x;++y;
            cut(x,y);
        }else if(s[1]=='m'){
            rd(x);rd(typ);scanf("%lf%lf",&a,&b);
            ++x;
            access(x);splay(x);
            t[x].f=init(typ,a,b);
            pushup(x);
        }else {
//            cout<<" tr "<<endl;
            rd(x);rd(y);scanf("%lf",&a);
            ++x;++y;
//            cout<<x<<" "<<y<<" a "<<a<<endl;
            if(findrt(x)==findrt(y)) printf("%.10lf\n",query(x,y,a));
            else puts("unreachable");
        }
    }
    return 0;
}

}
signed main(){
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
   Date: 2019/4/11 20:11:40
*/

 多项式可以支持合并

posted @ 2019-04-12 07:30  *Miracle*  阅读(251)  评论(0编辑  收藏  举报