• CF802L Send the Fool Further! (hard) 树上高斯消元


    朴素的高斯消元是 $O(n^3)$ 的,但是由于叶节点是终止节点,所以可以逐层向上推成 $k imes f(fa)+b$ 的形式.  

    推到根节点时直接取根节点的 $b$ 值就可以了. 

    code: 

    #include <cstdio> 
    #include <cstring> 
    #include <algorithm>   
    #define ll long long  
    #define mod 1000000007     
    #define N 100067
    #define setIO(s) freopen(s".in","r",stdin)  
    using namespace std;
    int qpow(int x,int y) 
    {
    	int tmp=1; 
    	for(;y;y>>=1,x=(ll)x*x%mod)   
    		if(y&1) 
    			tmp=(ll)tmp*x%mod;   
    	return tmp;  
    }   
    int n,edges;   
    int deg[N],hd[N],to[N<<1],nex[N<<1],val[N<<1],k[N],b[N];         
    void add(int u,int v,int c) 
    {
    	nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c; 
    }
    void dfs(int x,int ff,int pr) 
    {    
    	// deg[x]=1;   
    	for(int i=hd[x];i;i=nex[i]) if(to[i]!=ff) dfs(to[i],x,val[i]); // ,++deg[x];     
    	if(deg[x]==1)  k[x]=0,b[x]=0;     
    	else        
    	{               
    		int len=0; 
    		int bb=0;     
    		int kk=0;    
    		for(int i=hd[x];i;i=nex[i])  if(to[i]!=ff)  (kk+=k[to[i]])%=mod;  
    		for(int i=hd[x];i;i=nex[i])  len+=val[i];   
    		for(int i=hd[x];i;i=nex[i])  if(to[i]!=ff)  (bb+=b[to[i]])%=mod;                 
    		int t=(ll)qpow((deg[x]-kk+mod)%mod,mod-2);
    		b[x]=(ll)(bb+len)*t%mod;   
    		k[x]=t;    
    	}
    }
    int main() 
    {  
    	// setIO("input");  
    	scanf("%d",&n); 
    	int i,j;  
    	for(i=1;i<n;++i) 
    	{ 
    		int x,y,z;   
    		scanf("%d%d%d",&x,&y,&z),++x,++y;
    		++deg[x],++deg[y];    
    		add(x,y,z),add(y,x,z);    
    	} 
    	dfs(1,0,0);  
    	printf("%d
    ",(ll)b[1]%mod);         
    	return 0;   
    }
    

      

  • 相关阅读:
    MyBatis常见面试题以及解读
    如何防止sql注入攻击
    宝塔Linux面板基础命令
    Centos7配置静态ip
    宝塔Linux面板安装
    idea中安装阿里巴巴的代码规范插件
    idea中快速将类中的属性转为Json字符串的插件
    创建线程的四种方式
    sleep()方法与wait()方法的区别
    解决线程安全的几种方式
  • 原文地址:https://www.cnblogs.com/guangheli/p/12399128.html
Copyright © 2020-2023  润新知