[BZOJ5020][THUWC 2017]在美妙的數學王國中暢游


數學王國里有n座城市,每座城市有三個參數\(f\)\(a\)\(b\),一個智商為\(x\)的人經過一座城市的獲益\(f(x)\)
\(f=1\),則\(f(x)=\sin(ax+b)\)
\(f=2\),則\(f(x)=e^{ax+b}\)
\(f=3\),則\(f(x)=ax+b\)
會發生如下四種事件:
1、有兩個城市之間新建了道路;
2、有兩個城市之間的道路被摧毀了;
3、城市i的三個參數被修改了;
4、求智商為x的人從u走到v的獲益總和。
保證任何時候圖是一個森林。

題解

這是一道數學題

如果每座城市的\(f\)都是\(3\)你會做嗎?
很簡單,LCT維護一下路徑上的\(\sum a,\sum b\)即可。
可見我們維護出來的就是函數的一次項系數和常系數。
所以說,如果我告訴你每座城市都是一個不超過13項的多項式函數,你應該不會還不知道怎么做了吧。
但顯然這\(\sin(ax+b)\)啊,什么\(e^{ax+b}\)啊,這都是些什么鬼。
但如果我可以把它們展開成多項式呢?
根據泰勒公式,我們有

\[f(x)=\sum_{i=0}^{n} \frac{f^{(i)}(x_0)*(x-x_0)^i}{i!} \]

其中\(f^{(i)}(x)\)表示函數\(f(x)\)\(i\)階導。
上式是一個近似式,近似度隨\(n\)的取值而不斷遞增。要精確到題目要求的1e-7的話\(n\)只要取12,13就可以了。

數學小課堂——關於指數函數、三角函數、復活(霧)函數的求導

指數函數的求導

\[(a^x)'=a^x*\ln a \]

(\(\ln a\)代表取自然對數)。
特殊的,

\[(e^x)'=e^x \]

三角函數的求導

\[(\sin x)'=\cos x \]

\[(\cos x)'=-\sin x \]

\[(-\sin x)'=-\cos x \]

\[(-\cos x)'=\sin x \]

(所以說是循環四個,周期!)
復合函數

\[[f(g(x))]'=g'(x)*f'(g(x)) \]

放到這道題里面去

\[\sin'(ax+b)=a\cos(ax+b) \]

\[\sin''(ax+b)=-a^2\sin(ax+b) \]

\[\sin'''(ax+b)=-a^3\cos(ax+b) \]

以此類推

\[(e^{ax+b})^{(n)}=a^ne^{ax+b} \]

一次函數就不說了
然后這題就做完了

code

upt 18-08-07 : 更新了一份代碼,現在\(BZ\)能過了雖然是在最后一版

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N = 100005;
const int M = 16;
int n,m,fa[N],ch[2][N],rev[N],f[N],Stack[N],top;
double jc[M],sum[M][N],a[N],b[N];
char type[N],s[N];
bool son(int x){
	return ch[1][fa[x]]==x;
}
bool isroot(int x){
	return ch[0][fa[x]]!=x&&ch[1][fa[x]]!=x;
}
void reverse(int x){
	if (!x) return;
	swap(ch[0][x],ch[1][x]);rev[x]^=1;
}
void pushup(int x){
    for (int i=0;i<M;++i)
        sum[i][x]=sum[i][ch[0][x]]+sum[i][ch[1][x]];
    if (f[x]==1){
        double val=1,Sin=sin(b[x]),Cos=cos(b[x]);
        for (int i=0;i<M;i+=4){
            sum[i][x]+=Sin*val;val*=a[x];
			sum[i+1][x]+=Cos*val;val*=a[x];
			sum[i+2][x]-=Sin*val;val*=a[x];
			sum[i+3][x]-=Cos*val;val*=a[x];
        }
    }
    if (f[x]==2){
        double val=exp(b[x]);sum[0][x]+=val;
        for (int i=1;i<M;++i)
            val*=a[x],sum[i][x]+=val;
    }
    if (f[x]==3)
        sum[0][x]+=b[x],sum[1][x]+=a[x];
}
void pushdown(int x){
	if (!rev[x]) return;
	reverse(ch[0][x]);reverse(ch[1][x]);rev[x]=0;
}
void rotate(int x){
	int y=fa[x],z=fa[y],c=son(x);
	ch[c][y]=ch[c^1][x];if (ch[c][y]) fa[ch[c][y]]=y;
	fa[x]=z;if (!isroot(y)) ch[son(y)][z]=x;
	ch[c^1][x]=y;fa[y]=x;pushup(y);
}
void splay(int x){
    Stack[++top]=x;
    for (int i=x;!isroot(i);i=fa[i])
        Stack[++top]=fa[i];
    while (top) pushdown(Stack[top--]);
    for (int y=fa[x];!isroot(x);rotate(x),y=fa[x])
		if (!isroot(y)) son(x)^son(y)?rotate(x):rotate(y);
    pushup(x);
}
void access(int x){
	for (int y=0;x;y=x,x=fa[x])
		splay(x),ch[1][x]=y,pushup(x);
}
void makeroot(int x){
	access(x);splay(x);reverse(x);
}
int findroot(int x){
	access(x);splay(x);
	while(ch[0][x])x=ch[0][x];
	splay(x);return x;
}
void split(int x,int y){
	makeroot(x);access(y);splay(y);
}
void link(int x,int y){
	makeroot(x);fa[x]=y;
}
void cut(int x,int y){
	split(x,y);ch[0][y]=fa[x]=0;
}
int main(){
//  freopen("math.in","r",stdin);
//	freopen("math.out","w",stdout);
    jc[0]=1;
    for (int i=1;i<M;++i)
        jc[i]=jc[i-1]*i;
    scanf("%d %d %s",&n,&m,type);
    for (int i=1;i<=n;++i)
        scanf("%d %lf %lf",&f[i],&a[i],&b[i]);
    while (m--){
        int u,v,ff;
        double aa,bb,x,IQ,ans;
        scanf("%s",s);
        if (s[0]=='a'){
            scanf("%d %d",&u,&v);
            ++u;++v;link(u,v);
        }
        if (s[0]=='d'){
            scanf("%d %d",&u,&v);
            ++u;++v;cut(u,v);
        }
        if (s[0]=='m'){
            scanf("%d %d %lf %lf",&u,&ff,&aa,&bb);
            ++u;makeroot(u);
            f[u]=ff;a[u]=aa;b[u]=bb;
            pushup(u);
        }
        if (s[0]=='t'){
            scanf("%d %d %lf",&u,&v,&IQ);x=1;
            ++u;++v;
            if (findroot(u)^findroot(v)) {puts("unreachable");continue;}
            split(u,v);
            ans=0;
            for (int i=0;i<M;++i)
				ans+=sum[i][v]*x/jc[i],x*=IQ;
            printf("%.8e\n",ans);
        }
    }
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM