zoukankan      html  css  js  c++  java
  • [被踩计划] 题解 [省选联考 2020 A 卷] 作业题

    为什么叫被踩记录呢?因为感觉自己之前真的是太菜了,打算把之前联赛等考过的题目做一做,看看自已以前有多菜,所以取名叫被踩记录。

    题目链接

    题目分析

    [(sum_{i=1}^{n-1}w_{e_i}) imes gcd(w_{e_1},w_{e_2},dots,w_{e_{n-1}})= ]

    [(sum_{i=1}^{n-1}w_{e_i}) imes sum_{dmid w_{e_1},dmid w_{e_2},dots,dmid w_{e_{n-1}}}varphi(d)= ]

    [sum_{d}varphi(d)sum_{i=1}^{n-1}w_{e_i}[dmid w_{e_1}][dmid w_{e_2}]dots[dmid w_{e_{n-1}}] ]

    考虑枚举 (d) ,然后求里面的东西,也就是 (sum_{T}sum_{e_iin T} w_{e_i}) ,这个可以用矩阵树做,让第 (i) 条边边权为 (1+w_ix) ,那么最终一次项系数就是答案,为什么呢?发现我们实际上求的就是 (sum w_{e_i} imes sum_{T,e_iin T}) ,这个显然是没有问题。

    由于我们只要求一次项系数,所以可以在 (mod x^2) 意义下求解,乘法加法等很容易求,关键就是求逆元,设 (a+bx) 的逆元是 (Ax+B) ,那么有 ((Ax+B)(ax+b)equiv (Ab+Ba)x+Bbequiv 1 pmod {x^2}) ,于是 (Bequiv frac{1}{b},A=-frac{Ba}{b})

    注意到我们只需要枚举边数至少是 (n-1)(d) 就行了,这样的话复杂度大概是 (mathcal O(n^4 imes 144)) 的,具体我也不会证,可以看看这里

    参考代码

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ch() getchar()
    #define pc(x) putchar(x)
    using namespace std;
    template<typename T>void read(T&x){
    	static char c;static int f;
    	for(c=ch(),f=1;c<'0'||c>'9';c=ch())if(c=='-')f=-f;
    	for(x=0;c>='0'&&c<='9';c=ch())x=x*10+(c&15);x*=f;
    }
    template<typename T>void write(T x){
    	static char q[65];int cnt=0;
    	if(x<0)pc('-'),x=-x;
    	q[++cnt]=x%10,x/=10;
    	while(x)
    		q[++cnt]=x%10,x/=10;
    	while(cnt)pc(q[cnt--]+'0');
    }
    const int mod=998244353,maxn=35,maxw=160000,maxm=505;
    int mo(const int x){
    	return x>=mod?x-mod:x;
    }
    int power(int a,int x){
    	int re=1;
    	while(x){
    		if(x&1)re=1ll*re*a%mod;
    		a=1ll*a*a%mod,x>>=1;
    	}
    	return re;
    }
    struct Int{
    	int a,b;
    	Int(int a=0,int b=0):
    		a(a),b(b){}
    	Int operator + (const Int o)const{
    		return Int(mo(a+o.a),mo(b+o.b));
    	}
    	Int operator - (const Int o)const{
    		return Int(mo(mod-o.a+a),mo(mod-o.b+b));
    	}
    	Int operator * (const Int o)const{
    		return Int(1ll*a*o.a%mod,mo(1ll*a*o.b%mod+1ll*b*o.a%mod));
    	}
    	Int operator / (const Int o)const{
    		if(o.a==0)return Int(1ll*b*power(o.b,mod-2)%mod,0);		
    		int tmp=power(o.a,mod-2);
    		return Int(1ll*a*tmp%mod,1ll*tmp*tmp%mod*mo(mod-1ll*a*o.b%mod+1ll*b*o.a%mod)%mod);
    	}
    	Int operator += (const Int o){
    		return *this=*this+o;
    	}
    	Int operator -= (const Int o){
    		return *this=*this-o;
    	}
    	bool operator > (const Int o)const{
    		return a^o.a?a>o.a:b>o.b;
    	}
    };
    Int A[maxn][maxn];
    int solve(int n){
    	int re=0;
    	for(int i=1;i<n;++i){
    		int mx=i;
    		for(int j=i+1;j<n;++j)
    			if(A[j][i]>A[mx][i])
    				mx=j;
    		if(A[mx][i].a==0&&A[mx][i].b==0)
    			return 0;
    		if(mx!=i){
    			re^=1;
    			swap(A[mx],A[i]);
    		}
    		for(int j=1;j<n;++j){
    			if(i==j)continue;
    			Int tmp=A[j][i]/A[i][i];
    			for(int k=i;k<n;++k)
    				A[j][k]-=A[i][k]*tmp;
    		}
    	}
    	re=re?mod-1:1;
    	Int o=Int(1,0);
    	for(int i=1;i<n;++i)o=o*A[i][i];
    	return re=1ll*re*o.b%mod;
    }
    int cnt[maxw],S[maxm],T[maxm],W[maxm];
    int main(){
    	int n,m;read(n),read(m);
    	for(int i=1;i<=m;++i){
    		int u,v,w;
    		read(u),read(v),read(w);
    		int tmp=sqrt(w);
    		for(int j=1;j<=tmp;++j){
    			if(w%j==0){
    				++cnt[j];
    				if(j*j!=w)
    					++cnt[w/j];
    			}
    		}
    		S[i]=u,T[i]=v,W[i]=w;
    	}
    	int ans=0;
    	for(int i=1;i<=152501;++i){
    		if(cnt[i]<n-1)continue;
    		int tmp=sqrt(i),cp=i,phi=i;
    		for(int i=2;i<=tmp&&cp>1;++i){
    			if(cp%i==0){
    				phi=phi/i*(i-1);
    				while(cp%i==0)cp/=i;
    			}
    		}
    		if(cp>1)phi=phi/cp*(cp-1);
    		memset(A,0,sizeof A);
    		for(int j=1;j<=m;++j){
    			if(W[j]%i!=0)continue;
    			Int x=Int(1,W[j]);
    			A[S[j]][S[j]]+=x;
    			A[T[j]][T[j]]+=x;
    			A[S[j]][T[j]]-=x;
    			A[T[j]][S[j]]-=x;
    		}
    		ans=mo(ans+1ll*phi*solve(n)%mod);
    	}
    	write(ans),pc('
    ');
    	return 0;
    }
    
    
  • 相关阅读:
    linux 解压tgz 文件指令
    shell 脚本没有执行权限 报错 bash: ./myshell.sh: Permission denied
    linux 启动solr 报错 Your Max Processes Limit is currently 31202. It should be set to 65000 to avoid operational disruption.
    远程查询批量导入数据
    修改 MZTreeView 赋权节点父节点选中子节点自动选中的问题
    关于乱码的问题解决记录
    我的网站优化之路
    对设计及重构的一点反思
    我的五年岁月
    奔三的路上
  • 原文地址:https://www.cnblogs.com/lsq147/p/13751873.html
Copyright © 2011-2022 走看看