zoukankan      html  css  js  c++  java
  • P6624

    如何评价一年多以后再来补省选题

    考虑莫反,枚举 gcd(以下 (T) 为生成树,(G) 为原图,(G[x]) 为只保留边权为 (x) 的倍数得到的子图,(T)(P) 的生成树不严格地记为 (Tin P)):

    [egin{aligned} ans&=sum_{Tin G}sumlimits_{i=1}^{n-1}w_{T_i}mathop{gcd}_{j=1}^{n-1}w_{T_j}\&=sum_kksum_{Tin G[k]}sum_{i=1}^{n-1}w_{T_i}left[mathop{gcd}_{j=1}^{n-1}dfrac{w_{T_j}}k=1 ight]\&=sum_kksum_{Tin G[k]}sum_{i=1}^{n-1}w_{T_i}sum_{omidfrac{w_{T_1}}k,frac{w_{T_2}}k,cdots,frac{w_{T_{n-1}}}k}mu(o)\&=sum_omu(o)sum_kksum_{Tin G[ko]}sum_{i=1}^{n-1}w_{T_i}\&=sum_omu(o)sum_kkoperatorname{calc}_{ko} end{aligned} ]

    由于值域有 (v=152501) 的良心限制,考虑计算出 (1sim v) 内每个 (operatorname{calc}_i)。那这就是个生成树权值和的和,把一次多项式塞进去跑矩阵树即可。总复杂度 (mathrm O!left(vn^3 ight)),4e9 了已经,考虑优化。

    显然只要计算那些满足有至少 (n-1) 条边边权为 (i) 的倍数的 (operatorname{calc}_i),其它的一个生成树都没有一定是 (0)。那这些有多少呢?到 SF 主页里查一下 (maxmathrm d) 大概是 (200) 以内,(m=mathrm O!left(n^2 ight)),所以把所有边权的因数放到一个可重集里,里面所有重数 (geq n-1) 的数最多有 (mathrm O!left(dfrac{200n^2}n ight)=mathrm O(200n)) 种。总复杂度 (mathrm O!left(200n^4 ight)),1e8 差不多行,实际上不是很跑的满。

    最后线对计算 (ans) 即可。

    code
    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    const int mod=998244353;
    int qpow(int x,int y){
    	int res=1;
    	while(y){
    		if(y&1)res=1ll*res*x%mod;
    		x=1ll*x*x%mod;
    		y>>=1;
    	}
    	return res;
    }
    int inv(int x){return qpow(x,mod-2);}
    const int N=40,M=N*N,V=152510;
    vector<int> prm;
    bool vis[V];
    int mu[V],dld[V+1];
    void sieve(){
    	mu[1]=1;
    	for(int i=2;i<V;i++){
    		if(!vis[i]){
    			prm.pb(i);
    			mu[i]=-1;
    			dld[i]=1;
    		}
    		for(int j=0;j<prm.size();j++){
    			int x=prm[j];
    			if(i*x>V)break;
    			vis[i*x]=true;
    			if(i%x){
    				mu[i*x]=mu[i]*mu[x];
    				dld[i*x]=i;
    			}
    			else{
    				dld[i*x]=dld[i];
    				if(dld[i*x]==1)mu[i*x]=0;
    				else mu[i*x]=mu[dld[i*x]]*mu[i*x/dld[i*x]];
    				break;
    			}
    		}
    	}
    }
    int n,m;
    int fr[M],to[M],w[M];
    int cnt[V];
    int det[V];
    struct poly{
    	int a,b;
    	poly(int x=0,int y=0){a=x,b=y;}
    	friend poly operator+(poly x,poly y){return poly((x.a+y.a)%mod,(x.b+y.b)%mod);}
    	friend poly operator-(poly x,poly y){return poly((x.a-y.a)%mod,(x.b-y.b)%mod);}
    	friend poly operator*(poly x,poly y){
    		return poly((1ll*x.a*y.b+1ll*x.b*y.a)%mod,1ll*x.b*y.b%mod);
    	}
    	friend poly operator/(poly x,poly y){
    		int a=x.a,b=x.b,c=y.a,d=y.b;
    		int e=(1ll*a*d-1ll*c*b)%mod*inv(1ll*d*d%mod)%mod,f=1ll*b*inv(d)%mod;
    		return poly(e,f);
    	}
    	void operator+=(poly x){*this=*this+x;}
    	void operator-=(poly x){*this=*this-x;}
    	void operator*=(poly x){*this=*this*x;}
    	void operator/=(poly x){*this=*this/x;}
    }a[N][N];
    void swp(int x,int y){
    	for(int i=1;i<=n;i++)swap(a[x][i],a[y][i]);
    }
    void tadd(int x,poly v,int y){
    	for(int i=1;i<=n;i++)a[y][i]+=v*a[x][i];
    }
    int gauss(){
    	poly ans(0,1);
    	for(int i=1;;i++){
    		int row=0,col=0;
    		for(int j=1;j<=n;j++){
    			for(int k=i;k<=n;k++)if(a[k][j].b){row=k,col=j;break;}
    			if(row)break;
    		}
    		if(!row)break;
    		swp(i,row);
    		poly iv=poly(0,1)/a[i][col];
    		for(int j=i+1;j<=n;j++)tadd(i,poly(0,-1)*a[j][col]*iv,j);
    	}
    	for(int i=1;i<=n;i++)ans=ans*a[i][i];
    	return ans.a;
    }
    int main(){
    	sieve();
    	cin>>n>>m;
    	for(int i=1;i<=m;i++)scanf("%d%d%d",fr+i,to+i,w+i),cnt[w[i]]++;
    	for(int i=1;i<=152501;i++){
    		int cnt0=0;
    		for(int j=i;j<=152501;j+=i)cnt0+=cnt[j];
    		if(cnt0<n-1)continue;
    		memset(a,0,sizeof(a));
    		for(int j=1;j<=m;j++)if(w[j]%i==0){
    			int x=fr[j],y=to[j],v=w[j];
    			a[x][x]+=poly(v,1),a[y][y]+=poly(v,1);
    			a[x][y]-=poly(v,1),a[y][x]-=poly(v,1);
    		}
    		n--,det[i]=gauss(),n++;
    //		cout<<i<<":"<<det[i]<<"!!
    ";
    	}
    	int ans=0;
    	for(int o=1;o<V;o++)for(int k=1;k*o<V;k++)(ans+=1ll*mu[o]*k*det[k*o]%mod)%=mod;
    	cout<<(ans+mod)%mod;
    	return 0;
    }
    
    珍爱生命,远离抄袭!
  • 相关阅读:
    blk_update_request: I/O error, dev fd0, sector 0
    将MySQL数据迁移到Redis
    专职DBA-MySQL DAL(Data Access Layer)中间件总结
    搞笑聊天(一)
    看图写话(一)
    NFS存储服务
    rsync备份服务
    专职DBA-使用Python操作MySQL数据库
    如何解决SecureCRT无法选择Monaco等其他字体
    MySQL架构类型
  • 原文地址:https://www.cnblogs.com/ycx-akioi/p/solution-p6624.html
Copyright © 2011-2022 走看看