zoukankan      html  css  js  c++  java
  • BZOJ5020: [THUWC 2017]在美妙的数学王国中畅游(LCT,泰勒展开,二项式定理)

    Description

    数字和数学规律主宰着这个世界。
     
    机器的运转,
     
    生命的消长,
     
    宇宙的进程,
     
    这些神秘而又美妙的过程无不可以用数学的语言展现出来。
     
    这印证了一句古老的名言:
     
    “学好数理化,走遍天下都不怕。”
     
    学渣小R被大学的数学课程虐得生活不能自理,微积分的成绩曾是他在教室里上的课的最低分。然而他的某位陈姓室友却能轻松地在数学考试中得到满分。为了提升自己的数学课成绩,有一天晚上(在他睡觉的时候),他来到了数学王国。
     
    数学王国中,每个人的智商可以用一个属于 [0,1]的实数表示。数学王国中有 n 个城市,编号从 0 到 n−1 ,这些城市由若干座魔法桥连接。每个城市的中心都有一个魔法球,每个魔法球中藏有一道数学题。每个人在做完这道数学题之后都会得到一个在 [0,1] 区间内的分数。一道题可以用一个从 [0,1] 映射到 [0,1]的函数 f(x) 表示。若一个人的智商为 x ,则他做完这道数学题之后会得到 f(x)分。函数 f有三种形式:
     
        正弦函数 sin(ax+b) (a∈[0,1],b∈[0,π],a+b∈[0,π])
     
        指数函数 e^(ax+b) (a∈[−1,1],b∈[−2,0],a+b∈[−2,0])
     
        一次函数 ax+b (a∈[−1,1],b∈[0,1],a+b∈[0,1]
    数学王国中的魔法桥会发生变化,有时会有一座魔法桥消失,有时会有一座魔法桥出现。但在任意时刻,只存在至多一条连接任意两个城市的简单路径(即所有城市形成一个森林)。在初始情况下,数学王国中不存在任何的魔法桥。
    数学王国的国王拉格朗日很乐意传授小R数学知识,但前提是小R要先回答国王的问题。这些问题具有相同的形式,即一个智商为 x 的人从城市 u 旅行到城市 v(即经过 u 到 v 这条路径上的所有城市,包括 u和 v )且做了所有城市内的数学题后,他所有得分的总和是多少。

     

    Input

    第一行两个正整数 n,m 和一个字符串 type 。
    表示数学王国中共有 n 座城市,发生了 m 个事件,该数据的类型为 type 。 
    typet 字符串是为了能让大家更方便地获得部分分,你可能不需要用到这个输入。
    其具体含义在【数据范围与提示】中有解释。
     
    接下来 n 行,第 i 行表示初始情况下编号为 i 的城市的魔法球中的函数。
    一个魔法用一个整数 f表示函数的类型,两个实数 a,b 表示函数的参数,若
        f=1,则函数为 f(x)=sin(ax+b)(a∈[0,1],b∈[0,π],a+b∈[0,π])
        f=2,则函数为 f(x)=e^(ax+b)(a∈[−1,1],b∈[−2,0],a+b∈[−2,0])
        f=3,则函数为 f(x)=ax+b(a∈[−1,1],b∈[0,1],a+b∈[0,1])
    接下来 m行,每行描述一个事件,事件分为四类。
        appear u v 表示数学王国中出现了一条连接 u 和 v 这两座城市的魔法桥 (0≤u,v<n,u≠v) ,保证连接前 u和 v 这两座城市不能互相到达。
        disappear u v 表示数学王国中连接 u 和 v 这两座城市的魔法桥消失了,保证这座魔法桥是存在的。
        magic c f a b 表示城市 c 的魔法球中的魔法变成了类型为 f ,参数为 a,b 的函数
        travel u v x 表示询问一个智商为 x 的人从城市 u 旅行到城市 v 
    (即经过 u到 v 这条路径上的所有城市,包括 u 和 v )后,他得分的总和是多少。
     若无法从 u 到达 v ,则输出一行一个字符串 unreachable。
    1≤n≤100000,1≤m≤200000

     

    Output

    对于每个询问,输出一行实数,表示得分的总和。

     

    Sample Input

    3 7 C1
    1 1 0
    3 0.5 0.5
    3 -0.5 0.7
    appear 0 1
    travel 0 1 0.3
    appear 0 2
    travel 1 2 0.5
    disappear 0 1
    appear 1 2
    travel 1 2 0.5

    Sample Output

    9.45520207e-001
    1.67942554e+000
    1.20000000e+000

    解题思路:

    题目描述如此毒瘤。

    从操作3得到的启发,将多项式展开对应项相加。

    这道题可以将sin(ax+b),eax+b泰勒展开。

    精度的话16位肯定够。剩下的就是裸的LCT了。

    听霉霉的歌写泰勒展开不容易错

    代码:

     

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lll tr[spc].ch[0]
      5 #define rrr tr[spc].ch[1]
      6 #define ls ch[0]
      7 #define rs ch[1]
      8 const int N=100010;
      9 const int oo=16;
     10 struct trnt{
     11     int ch[2];
     12     int fa;
     13     int lzt;
     14     int type;
     15     bool anc;
     16     double a,b;
     17     double C[oo];
     18     double f[oo];
     19     double val(double x)
     20     {
     21         double ans=f[0];
     22         double t=x;
     23         for(int i=1;i<oo;i++,t*=x)
     24             ans+=f[i]*t;
     25         return ans;
     26     }
     27     void Insert(void)
     28     {
     29         scanf("%d",&type);
     30         scanf("%lf%lf",&a,&b);
     31         return ;
     32     }
     33     void Taylor(double *fac)
     34     {
     35         double at[oo],bt[oo];
     36         for(int i=0;i<oo;i++)
     37             C[i]=at[i]=bt[i]=0;
     38         at[0]=1;
     39         bt[0]=1;
     40         for(int i=1;i<oo;i++)
     41             at[i]=at[i-1]*a,bt[i]=bt[i-1]*b;
     42         if(type==1)
     43         {//sin(ax+b)
     44             double tmp=1;
     45             for(int i=1;i<oo;i+=2)
     46             {
     47                 for(int j=0;j<=i;j++)
     48                     C[j]+=tmp*at[j]*bt[i-j]/fac[j]/fac[i-j];
     49                 tmp*=-1.00;
     50             }
     51             return ;
     52         }
     53         if(type==2)
     54         {//e^(ax+b)
     55             for(int i=0;i<oo;i++)
     56             {
     57                 for(int j=0;j<=i;j++)
     58                     C[j]+=fac[i]/fac[j]/fac[i-j]*at[j]*bt[i-j]/fac[i];
     59             }
     60             return ;
     61         }
     62         if(type==3)
     63         {
     64             C[0]=b;
     65             C[1]=a;
     66             return ;
     67         }
     68     }
     69 }tr[N];
     70 int n,m;
     71 double fac[50];
     72 char tmp[10000];
     73 bool whc(int spc)
     74 {
     75     return tr[tr[spc].fa].rs==spc;
     76 }
     77 void pushup(int spc)
     78 {
     79     for(int i=0;i<oo;i++)
     80         tr[spc].f[i]=tr[spc].C[i];
     81     if(lll)
     82         for(int i=0;i<oo;i++)
     83             tr[spc].f[i]+=tr[lll].f[i];
     84     if(rrr)
     85         for(int i=0;i<oo;i++)
     86             tr[spc].f[i]+=tr[rrr].f[i];
     87     return ;
     88 }
     89 void trr(int spc)
     90 {
     91     if(!spc)
     92         return ;
     93     std::swap(lll,rrr);
     94     tr[spc].lzt^=1;
     95     return ;
     96 }
     97 void pushdown(int spc)
     98 {
     99     if(tr[spc].lzt)
    100     {
    101         trr(lll);
    102         trr(rrr);
    103         tr[spc].lzt=0;
    104     }
    105     return ;
    106 }
    107 void recal(int spc)
    108 {
    109     if(!tr[spc].anc)
    110         recal(tr[spc].fa);
    111     pushdown(spc);
    112     return ;
    113 }
    114 void rotate(int spc)
    115 {
    116     int f=tr[spc].fa;
    117     bool k=whc(spc);
    118     tr[f].ch[k]=tr[spc].ch[!k];
    119     tr[spc].ch[!k]=f;
    120     if(tr[f].anc)
    121     {
    122         tr[f].anc=0;
    123         tr[spc].anc=1;
    124     }else
    125         tr[tr[f].fa].ch[whc(f)]=spc;
    126     tr[spc].fa=tr[f].fa;
    127     tr[f].fa=spc;
    128     tr[tr[f].ch[k]].fa=f;
    129     pushup(f);
    130     pushup(spc);
    131     return ;
    132 }
    133 void splay(int spc)
    134 {
    135     recal(spc);
    136     while(!tr[spc].anc)
    137     {
    138         int f=tr[spc].fa;
    139         if(tr[f].anc)
    140         {
    141             rotate(spc);
    142             return ;
    143         }
    144         if(whc(spc)^whc(f))
    145             rotate(spc);
    146         else
    147             rotate(f);
    148         rotate(spc);
    149     }
    150     return ;
    151 }
    152 void access(int spc)
    153 {
    154     int lst=0;
    155     while(spc)
    156     {
    157         splay(spc);
    158         tr[rrr].anc=1;
    159         tr[lst].anc=0;
    160         rrr=lst;
    161         lst=spc;
    162         pushup(spc);
    163         spc=tr[spc].fa;
    164     }
    165     return ;
    166 }
    167 void Mtr(int spc)
    168 {
    169     access(spc);
    170     splay(spc);
    171     trr(spc);
    172     return ;
    173 }
    174 void split(int x,int y)
    175 {
    176     Mtr(x);
    177     access(y);
    178     splay(y);
    179     return ;
    180 }
    181 void link(int x,int y)
    182 {
    183     Mtr(x);
    184     tr[x].fa=y;
    185     return ;
    186 }
    187 bool together(int x,int y)
    188 {
    189     split(x,y);
    190     while(tr[y].ls)
    191         y=tr[y].ls;
    192     return x==y;
    193 }
    194 void cut(int x,int y)
    195 {
    196     split(x,y);
    197     tr[x].fa=0;
    198     tr[x].anc=true;
    199     tr[y].ls=0;
    200     pushup(y);
    201     return ;
    202 }
    203 int main()
    204 {
    205     scanf("%d%d",&n,&m);
    206     scanf("%s",tmp);
    207     fac[0]=1;
    208     for(int i=1;i<oo;i++)
    209     {
    210         double x=i;
    211         fac[i]=fac[i-1]*x;
    212     }
    213     for(int i=1;i<=n;i++)
    214     {
    215         tr[i].Insert();
    216         tr[i].Taylor(fac);
    217         tr[i].anc=1;
    218     }
    219     while(m--)
    220     {
    221         scanf("%s",tmp+1);
    222         if(tmp[1]=='a')
    223         {
    224             int a,b;
    225             scanf("%d%d",&a,&b);
    226             a++,b++;
    227             link(a,b);
    228         }else if(tmp[1]=='d')
    229         {
    230             int a,b;
    231             scanf("%d%d",&a,&b);
    232             a++,b++;
    233             cut(a,b);
    234         }else if(tmp[1]=='m')
    235         {
    236             int x;
    237             scanf("%d",&x);
    238             x++;
    239             splay(x);
    240             tr[x].Insert();
    241             tr[x].Taylor(fac);
    242         }else{
    243             int a,b;
    244             scanf("%d%d",&a,&b);
    245             double x;
    246             scanf("%lf",&x);
    247             a++,b++;
    248             if(!together(a,b))
    249                 puts("unreachable");
    250             else{
    251                 double ret=tr[b].val(x);
    252                 printf("%.8e
    ",ret);
    253             }
    254         }
    255     }
    256     return 0;
    257 }

     

     

  • 相关阅读:
    mysql表的操作
    mysql 索引
    JQuery
    js
    cobbler一键批量安装系统
    rabbitmq-cluster搭建
    KVM嵌套虚拟化nested之CPU透传
    kvm虚拟机管理
    dlib(【机器学习库】含有多线程网络容器等基础功能】)
    ScriptCommunicator(各种通讯方式测试串口can网络等)
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10116746.html
Copyright © 2011-2022 走看看