关于CSP S T4写树剖会不会被卡
  • 板块学术版
  • 楼主Prean
  • 当前回复3
  • 已保存回复3
  • 发布时间2022/10/29 22:57
  • 上次更新2023/10/27 05:00:20
查看原帖
关于CSP S T4写树剖会不会被卡
160839
Prean楼主2022/10/29 22:57

RT,考场写的树剖 代码长达7kb

出考场被同学告知会被卡常,结果在 lg 和 infOJ 都跑的飞快?

源码:

//你有没有想过,朋友不再是朋友,家园不再是家园!
//树剖DDP。。。。。。太怪了哥。。。。。。 
//他妈这题写了我90min,真分崩离析了 
//估分100 
#include<cstdio>
#include<cctype>
namespace SOLVE{
	typedef long long ll;
	inline int read(){
		int n(0);char s;while(!isdigit(s=getchar()));while(n=n*10+(s&15),isdigit(s=getchar()));return n;
	}
	inline void write(ll n){
		static char s[20];int top(0);while(s[++top]=n%10^48,n/=10);while(putchar(s[top]),--top);putchar(10);
	}
	const int M=2e5+5;const ll INF=1e18;
	int n,q,k,ege,dfc,h[M],w[M];int f[M],d[M],sz[M],son[M],top[M],dfn[M];
	int mx1[M],mx2[M],mx3[M];
	struct Edge{
		int v,nx;
	}e[M<<1];
	inline void Add(const int&u,const int&v){
		e[++ege]=(Edge){v,h[u]};h[u]=ege;
		e[++ege]=(Edge){u,h[v]};h[v]=ege;
	}
	inline ll min(const ll&a,const ll&b){
		return a>b?b:a;
	}
	template<int S>
	struct Matrix{
		ll f[S][S];
		Matrix(){
			for(int i=0;i^S;++i)for(int j=0;j^S;++j)f[i][j]=INF;
		}
		inline ll*operator[](const int&x){
			return f[x];
		}
		inline Matrix operator*(Matrix g){
			Matrix<S>ans=Matrix<S>();
			for(int i=0;i^S;++i)for(int j=0;j^S;++j)for(int k=0;k^S;++k)ans[i][j]=min(ans[i][j],f[i][k]+g[k][j]);
			return ans;
		}
	};
	template<int S>
	struct Vector{
		ll f[S];
		Vector(){
			for(int i=0;i^S;++i)f[i]=INF;
		}
		inline ll&operator[](const int&x){
			return f[x];
		}
		inline Vector operator*(Matrix<S>g){
			Vector<S>ans=Vector<S>();
			for(int i=0;i^S;++i)for(int j=0;j^S;++j)ans[j]=min(ans[j],f[i]+g[i][j]);
			return ans;
		}
	};
	inline void DFS1(const int&u){
		sz[u]=1;d[u]=d[f[u]]+1;
		for(int v,E=h[u];E;E=e[E].nx)if((v=e[E].v)^f[u])f[v]=u,DFS1(v),sz[u]+=sz[v],sz[v]>sz[son[u]]&&(son[u]=v);
	}
	inline void DFS2(const int&u,const int&tp){
		dfn[u]=++dfc;top[u]=tp;if(!son[u])return;DFS2(son[u],tp);
		for(int E=h[u];E;E=e[E].nx)if(e[E].v^son[u]&&e[E].v^f[u])DFS2(e[E].v,e[E].v);
	}
	inline int LCA(int u,int v){
		while(top[u]^top[v])d[top[u]]>d[top[v]]?u=f[top[u]]:v=f[top[v]];return d[u]>d[v]?v:u;
	}
	namespace SOL1{
		ll S[M];
		inline void DFS(const int&u){
			S[u]=S[f[u]]+w[u];for(int E=h[u];E;E=e[E].nx)if(e[E].v^f[u])DFS(e[E].v);
		}
		inline ll Qry(int s,int t){
			const int&lca=LCA(s,t);return S[s]+S[t]-S[lca]-S[f[lca]];
		}
		inline void Solve(){
			DFS(1);
			while(q--){
				int s,t;s=read();t=read();write(Qry(s,t));
			}
		}
	}
	namespace SOL2{
		Matrix<2>p1[M<<2],p2[M<<2],a[M];Vector<2>ans;
		inline Matrix<2>tr(const int&w){
			Matrix<2>ans;ans[0][0]=ans[1][0]=w;ans[0][1]=0;return ans;
		}
		inline void Build(const int&u,const int&L=1,const int&R=n){
			if(L==R)return void(p1[u]=p2[u]=a[L]);
			const int&mid=L+R>>1;Build(u<<1,L,mid);Build(u<<1|1,mid+1,R);
			p1[u]=p1[u<<1]*p1[u<<1|1];p2[u]=p2[u<<1|1]*p2[u<<1];
		}
		inline void Q1(const int&u,const int&l,const int&r,const int&L=1,const int&R=n){
			if(l>R||L>r)return;if(l<=L&&R<=r)return void(ans=ans*p1[u]);
			const int&mid=L+R>>1;Q1(u<<1,l,r,L,mid);Q1(u<<1|1,l,r,mid+1,R);
		}
		inline void Q2(const int&u,const int&l,const int&r,const int&L=1,const int&R=n){
			if(l>R||L>r)return;if(l<=L&&R<=r)return void(ans=ans*p2[u]);
			const int&mid=L+R>>1;Q2(u<<1|1,l,r,mid+1,R);Q2(u<<1,l,r,L,mid);
		}
		inline ll Qry(int s,int t){
			if(d[s]<d[t])s^=t^=s^=t;
			static int len,u[M],v[M];ans[0]=w[s];ans[1]=INF;len=0;s=f[s];
			while(top[s]^top[t]){
				if(d[top[s]]>d[top[t]])Q2(1,dfn[top[s]],dfn[s]),s=f[top[s]];
				else ++len,u[len]=top[t],v[len]=t,t=f[top[t]];
			}
			if(d[s]>d[t])Q2(1,dfn[t],dfn[s]);else Q1(1,dfn[s],dfn[t]);
			for(int i=len;i>=1;--i)Q1(1,dfn[u[i]],dfn[v[i]]);return ans[0];
		}
		inline void Solve(){
			for(int u=1;u<=n;++u)a[dfn[u]]=tr(w[u]);Build(1);
			while(q--){
				int s,t;s=read();t=read();write(Qry(s,t));
			}
		}
	}
	namespace SOL3{
		Matrix<3>p1[M<<2],p2[M<<2],a[M];Vector<3>ans;
		inline Matrix<3>tr1(const int&w,const int&x){
			Matrix<3>ans;ans[0][0]=ans[1][0]=ans[2][0]=w;ans[0][1]=ans[1][2]=0;ans[1][1]=x;return ans;
		}
		inline Matrix<3>tr2(const int&w){
			Matrix<3>ans;ans[0][0]=ans[1][0]=ans[2][0]=w;ans[0][1]=ans[1][2]=0;return ans;
		}
		inline void Build(const int&u,const int&L=1,const int&R=n){
			if(L==R)return void(p1[u]=p2[u]=a[L]);
			const int&mid=L+R>>1;Build(u<<1,L,mid);Build(u<<1|1,mid+1,R);
			p1[u]=p1[u<<1]*p1[u<<1|1];p2[u]=p2[u<<1|1]*p2[u<<1];
		}
		inline void Q1(const int&u,const int&l,const int&r,const int&L=1,const int&R=n){
			if(l>R||L>r)return;if(l<=L&&R<=r)return void(ans=ans*p1[u]);
			const int&mid=L+R>>1;Q1(u<<1,l,r,L,mid);Q1(u<<1|1,l,r,mid+1,R);
		}
		inline void Q2(const int&u,const int&l,const int&r,const int&L=1,const int&R=n){
			if(l>R||L>r)return;if(l<=L&&R<=r)return void(ans=ans*p2[u]);
			const int&mid=L+R>>1;Q2(u<<1|1,l,r,mid+1,R);Q2(u<<1,l,r,L,mid);
		}
		inline int Get(const int&u,const int&x,const int&y){
			if(mx1[u]!=x&&mx1[u]!=y)return w[mx1[u]];
			if(mx2[u]!=x&&mx2[u]!=y)return w[mx2[u]];
			return w[mx3[u]];
		}
		inline ll Qry(int s,int t){
			if(d[s]<d[t])s^=t^=s^=t;
			static int len,u[M],v[M];int V,lst(s);ans[0]=w[s];ans[1]=ans[2]=INF;len=0;s=f[s];
			while(top[s]^top[t]){
				if(d[top[s]]>d[top[t]]){
					V=Get(s,lst,f[s]);if(V)ans=ans*tr1(w[s],V);else ans=ans*tr2(w[s]);
					if(s!=top[s])Q2(1,dfn[top[s]],dfn[f[s]]);lst=top[s];s=f[top[s]];
				}
				else++len,u[len]=top[t],v[len]=t,t=f[top[t]];
			}
			u[len+1]=v[len+1]=0;
			if(d[s]>d[t]){
				if(s!=t){
					V=Get(s,lst,f[s]);if(V)ans=ans*tr1(w[s],V);else ans=ans*tr2(w[s]);
				}
				if(dfn[s]-1>=dfn[t]+1)Q2(1,dfn[t]+1,dfn[s]-1);
				if(s==t){
					V=Get(s,lst,u[len]);if(V)ans=ans*tr1(w[s],V);else ans=ans*tr2(w[s]);
				}
				else{
					V=Get(t,son[t],u[len]);if(V)ans=ans*tr1(w[t],V);else ans=ans*tr2(w[t]);
				}
			}
			else{
				if(s==t){
					V=Get(s,lst,u[len]);if(V)ans=ans*tr1(w[s],V);else ans=ans*tr2(w[s]);
				}
				else{
					V=Get(s,son[s],lst);if(V)ans=ans*tr1(w[s],V);else ans=ans*tr2(w[s]);
				}
				if(dfn[s]+1<=dfn[t]-1)Q1(1,dfn[s]+1,dfn[t]-1);
				if(s!=t){
					V=Get(t,u[len],f[t]);if(V)ans=ans*tr1(w[t],V);else ans=ans*tr2(w[t]);
				}
			}
			for(int i=len;i>=1;--i){
				if(u[i]!=v[i])Q1(1,dfn[u[i]],dfn[f[v[i]]]);
				V=Get(v[i],f[v[i]],u[i-1]);if(V)ans=ans*tr1(w[v[i]],V);else ans=ans*tr2(w[v[i]]);
			}
			return ans[0];
		}
		inline void Solve(){
			for(int V,u=1;u<=n;++u){
				V=Get(u,f[u],son[u]);if(V)a[dfn[u]]=tr1(w[u],V);else a[dfn[u]]=tr2(w[u]);
			}
			Build(1);
			while(q--){
				int s,t;s=read();t=read();write(Qry(s,t));
			}
		}
	}
	inline void main(){
		w[0]=1e9+1;n=read();q=read();k=read();for(int u=1;u<=n;++u)w[u]=read();
		for(int u,v,i=1;i<n;++i)u=read(),v=read(),Add(u,v);DFS1(1);DFS2(1,1);
		for(int u=1;u<=n;++u)for(int v,E=h[u];E;E=e[E].nx){
			v=e[E].v;
			if(w[v]<w[mx1[u]])mx3[u]=mx2[u],mx2[u]=mx1[u],mx1[u]=v;
			else if(w[v]<w[mx2[u]])mx3[u]=mx2[u],mx2[u]=v;
			else if(w[v]<w[mx3[u]])mx3[u]=v;
		}
		if(k==1)return SOL1::Solve();if(k==2)return SOL2::Solve();if(k==3)return SOL3::Solve();
	}
}
int main(){
	SOLVE::main();
	return 0;
}
2022/10/29 22:57
加载中...