zoukankan      html  css  js  c++  java
  • [THUWC2017] 在美妙的数学王国畅游

    Description

    懒得概括了。。

    Solution

    挺裸的LCT+挺裸的泰勒展开吧... 稍微了解过一点的人应该都能很快切掉...吧?

    就是把每个点的函数泰勒展开一下然后LCT维护子树sum就行了

    嗯还是挺傻逼的

    记住sin(x)求导是cos(x) md为了这个调了好久

    吐槽:

    我就纳了逼闷了最优解为什么这么容易

    最开始写完交发现最优解第四,然后写了个double类型的读优然后慢了4000ms...然后不知从哪听说cin读浮点数快的一批然后又换cin就又慢了10000ms... 最后突然想起来最影响时间的是项数,就把展开的项数从16变成12直接跑第一了2333..

    Code

    #include<bits/stdc++.h>
    using std::min;
    using std::max;
    using std::swap;
    using std::vector;
    typedef double db;
    typedef long long ll;
    #define pb(A) push_back(A)
    #define pii std::pair<int,int>
    #define all(A) A.begin(),A.end()
    #define mp(A,B) std::make_pair(A,B)
    const int N=1e5+5;
    const int maxn=12;
    #define ls ch[x][0]
    #define rs ch[x][1]
    
    char s[20];
    int rev[N],stk[N],top;
    int n,m,ch[N][2],fa[N];
    db sum[N][maxn+5],val[N][maxn+5];
    
    void pushup(int x){
        for(int i=0;i<maxn;i++)
            sum[x][i]=sum[ls][i]+sum[rs][i]+val[x][i];
    }
    
    void pushr(int x){
        rev[x]^=1;swap(ls,rs);
    }
    
    void pushdown(int x){
        if(rev[x]) pushr(ls),pushr(rs),rev[x]=0;
    }
    
    bool nroot(int x){
        return ch[fa[x]][0]==x or ch[fa[x]][1]==x;
    }
    
    void rotate(int x){
        int y=fa[x],z=fa[y],d=ch[y][1]==x,dd=ch[z][1]==y;
        fa[x]=z;if(nroot(y)) ch[z][dd]=x;
        ch[y][d]=ch[x][d^1];if(ch[x][d^1]) fa[ch[x][d^1]]=y;
        ch[x][d^1]=y;fa[y]=x;pushup(y);
    }
    
    void splay(int x){
        int now=x;stk[++top]=now;
        while(nroot(now)) now=fa[now],stk[++top]=now;
        while(top) pushdown(stk[top--]);
        while(nroot(x)){
            int y=fa[x],z=fa[y];
            if(nroot(y)) rotate((ch[y][1]==x)^(ch[z][1]==y)?x:y);
            rotate(x);
        } pushup(x);
    }
    
    void calc(int opt,db a,db b,int id){
        if(opt==1){
            db x=sin(b),y=cos(b),now=1;
            for(int i=0;i<maxn;i++)
                val[id][i]=((i&1)?(i%4==1?y:-y):(i%4==0?x:-x))*now,now*=a;
        } else if(opt==2){
            db x=exp(b),now=1;
            for(int i=0;i<maxn;i++)
                val[id][i]=x*now,now*=a;
        } else{
            val[id][0]=b;val[id][1]=a;
            for(int i=2;i<maxn;i++) 
                val[id][i]=0;
        }
    }
    
    void access(int x){
        for(int y=0;x;y=x,x=fa[x])
            splay(x),rs=y,pushup(x);
    }
    
    void makeroot(int x){
        access(x),splay(x),pushr(x);
    }
    
    void link(int x,int y){
        makeroot(x),fa[x]=y;
    }
    
    void split(int x,int y){
        makeroot(x),access(y),splay(y);
    }
    
    void cut(int x,int y){
        split(x,y);
        fa[x]=ch[y][0]=0;pushup(y);
    }
    
    int findroot(int x){
        while(ls) pushdown(x),x=ls;
        return x;
    }
    
    int getint(){
        int X=0,w=0;char ch=getchar();
        while(!isdigit(ch))w|=ch=='-',ch=getchar();
        while( isdigit(ch))X=X*10+ch-48,ch=getchar();
        if(w) return -X;return X;
    }
    
    signed main(){
        n=getint(),m=getint();scanf("%s",s);
        for(int i=1;i<=n;i++){
            int opt=getint();db a,b;
            scanf("%lf%lf",&a,&b);calc(opt,a,b,i); 
            pushup(i);
        }
        while(m--){
            scanf("%s",s);
            if(s[0]=='a'){
                int x=getint()+1,y=getint()+1;
                link(x,y);
            } else if(s[0]=='d'){
                int x=getint()+1,y=getint()+1;
                cut(x,y);
            } else if(s[0]=='m'){
                int id=getint()+1,opt=getint();
                db a,b;scanf("%lf%lf",&a,&b);
                splay(id),calc(opt,a,b,id),pushup(id);
            } else{
                int a=getint()+1,b=getint()+1;
                db x;scanf("%lf",&x);
                split(a,b);
                if(findroot(b)!=a){puts("unreachable");continue;}
                db ans=sum[b][0],now=1,noww=1;
                for(int i=1;i<maxn;i++)
                    noww*=x,now*=i,ans+=sum[b][i]*noww/now;
                printf("%.9lf
    ",ans);
            }
        } return 0;
    }
    
    
  • 相关阅读:
    遗传算法(Genetic Algorithm, GA)及MATLAB实现
    CCF CSP 201809-2 买菜
    PAT (Basic Level) Practice (中文)1008 数组元素循环右移问题 (20 分)
    PAT (Basic Level) Practice (中文)1006 换个格式输出整数 (15 分)
    PAT (Basic Level) Practice (中文)1004 成绩排名 (20 分)
    PAT (Basic Level) Practice (中文)1002 写出这个数 (20 分)
    PAT (Advanced Level) Practice 1001 A+B Format (20 分)
    BP神经网络(原理及MATLAB实现)
    问题 1676: 算法2-8~2-11:链表的基本操作
    问题 1744: 畅通工程 (并查集)
  • 原文地址:https://www.cnblogs.com/YoungNeal/p/10300656.html
Copyright © 2011-2022 走看看