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

Orz w_yqts
lct+泰勒展开

#include <bits/stdc++.h>
using namespace std;
#define db double
#define N 666666
#define m 20
struct lct
{
    int c[2],f,rev;
    db s[m],v[m];
}tr[N];
db C[m][m];
int top,stk[N];
inline int isroot(int x)
{
    return (!tr[x].f) || (tr[tr[x].f].c[0]!=x && tr[tr[x].f].c[1]!=x);
}
inline void update(int x)
{
    int l=tr[x].c[0],r=tr[x].c[1];
    for (int i=0;i<m;++i) tr[x].s[i]=tr[x].v[i]+tr[l].s[i]+tr[r].s[i];
}
inline void pushdown(int x)
{
    if (!tr[x].rev) return;
    int l=tr[x].c[0],r=tr[x].c[1];
    swap(tr[x].c[0],tr[x].c[1]);
    tr[l].rev^=1;tr[r].rev^=1;
    tr[x].rev=0;
}
inline void rotate(int x)
{
    int y=tr[x].f,z=tr[y].f,l,r;
    l=tr[y].c[1]==x,r=l^1;
    if (!isroot(y)) tr[z].c[tr[z].c[1]==y]=x;
    tr[tr[x].c[r]].f=y;tr[y].f=x;tr[x].f=z;
    tr[y].c[l]=tr[x].c[r];tr[x].c[r]=y;
    update(y);
}
inline void splay(int x)
{
    int t=x;
    while (!isroot(t)) stk[++top]=t,t=tr[t].f;
    stk[++top]=t;
    while (top) pushdown(stk[top--]);
    while (!isroot(x))
    {
        int y=tr[x].f,z=tr[y].f;
        if (!isroot(y))
        {
            if (tr[y].c[0]==x ^ tr[z].c[0]==y) rotate(x);
            else rotate(y);
        }
        rotate(x);
    }
    update(x);
}
inline void access(int x)
{
    int t=0,tt=x;
    while (x)
    {
        splay(x);
        tr[x].c[1]=t;
        update(x);
        t=x;x=tr[x].f;
    }
    splay(tt);
}
inline void makeroot(int x)
{
    access(x);tr[x].rev^=1;
}
int find(int x)
{
    while (tr[x].f) x=tr[x].f;
    return x;
}
inline void link(int x,int y)
{
    makeroot(x);
    tr[x].f=y;
}
inline void cut(int x,int y)
{
    makeroot(x);
    access(y);
    tr[y].c[0]=tr[x].f=0;
    update(y);
}
db ta[m],tb[m],fx[m],jc[m];
inline void modify(int x,int f,db fa,db fb)
{
    access(x);
    ta[0]=1.0;tb[0]=1.0;
    for (int i=1;i<m;++i) ta[i]=ta[i-1]*fa,tb[i]=tb[i-1]*fb;
    for (int i=0;i<m;++i) tr[x].v[i]=0.0;
    if (f==3) {tr[x].v[0]=fb;tr[x].v[1]=fa;return;}
    for (int i=0;i<m;++i)
    {
        for (int j=0;j<=i;++j)
        {
            db t=ta[j]*tb[i-j]*C[i][j]/jc[i];
            if (f==1)
            {
                if (i%2==0) t=0.0;
                else if (i%4==3) t=-t;
            }
            tr[x].v[j]+=t;
        }
    }
}
int n;
inline void solve()
{
    char type[100];
    int x,y,f;
    db fa,fb,iq;
    scanf("%s",type);
    if (type[0]=='a')
    {
        scanf("%d%d",&x,&y);
        ++x,++y;
        link(x,y);
        return;
    }
    if (type[0]=='d')
    {
        scanf("%d%d",&x,&y);
        ++x,++y;
        cut(x,y);
        return;
    }
    if (type[0]=='m')
    {
        scanf("%d%d%lf%lf",&x,&f,&fa,&fb);
        ++x;
        modify(x,f,fa,fb);
        update(x);
        return;
    }
    db ans=0.0;
    scanf("%d%d%lf",&x,&y,&iq);
    ++x,++y;
    if (find(x) != find(y)) {puts("unreachable");return;}
    makeroot(y);access(x);
    fx[0]=1.0;
    for (int i=1;i<m;++i) fx[i]=fx[i-1]*iq;
    for (int i=0;i<m;++i) ans+=fx[i]*tr[x].s[i];
    printf("%.8le\n",ans);
    //for (int i=0;i<m;++i) printf("%.2lf ",tr[x].s[i]);cout<<endl;
}
int main()
{
    int Q;
    char stype[100];
    jc[0]=1.0;
    for (int i=1;i<m;++i) jc[i]=jc[i-1]*i;
    C[0][0]=1.0;
    C[1][0]=C[1][1]=1.0;
    for (int i=2;i<m;++i)
    {
        C[i][0]=C[i][i]=1.0;
        for (int j=1;j<i;++j) C[i][j]=C[i-1][j-1]+C[i-1][j];
    }
    cin>>n>>Q;
    scanf("%s",stype);
    for (int i=1;i<=n;++i)
    {
        int f;
        db fa,fb;
        scanf("%d%lf%lf",&f,&fa,&fb);
        modify(i,f,fa,fb);
    }
    while (Q--) solve();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值