zoukankan      html  css  js  c++  java
  • small test on 5.30 morning T3

        经典的等价类计数问题,我们设 f(x) 为环长为 x 的时候的花环种类,那么答案显然等于 1/n  *  Σf( gcd (i,n) * [gcd(i,n)!=1] * [i>=0&&i<n])

        特殊的,因为循环节不能只有一个,所以gcd不能是1。(但是注意特判n==1的情况)

        又因为n很大,所以我们不能枚举gcd一个一个算,必须把n质因数分解之后用Φ算,这里推一波狮子就好啦。。。。

        然后就是f()的计算方法啦。。。首先我们设 g(x) = f(x) / k,也就是当环上第一个花颜色已经确定的方案数,显然 g(x) = (k-1)^(x-1) - g(x-1)       (x>2)

        x<=2的话g很好手算啦。。。所以考虑x>2的时候,从第2到第n个花都要和前面不同色,所以是 (k-1)^(n-1)。又因为这样会把第1个花和第n个花同色的方案算进来,所以还要减去g(x-1)  (相当于把第n个花去掉,只剩n-1个花成环,仍然要求相邻不同色)。

        这样通过递推式直接矩阵做的话会凉掉,因为自带8的大常数。。。。。

        不过介于这个递推式太jb简单了,我们都可以直接用等比数列求和求出它的通项。。。。 就是 g(x) =( (k-1)^n + (k-1) * (-1)^n )/k , 所以f(x) =  (k-1)^n + (k-1) * (-1)^n.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<ctime>
    #include<cmath>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int ha=998244353,P=ha-1;
    inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}
    inline void ADD(int &x,int y){ x+=y; if(x>=ha)x-=ha;}
    inline int ksm(int x,int y){ int an=1; for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha; return an;}
    
    int T,k,ans,c[233],num=0;
    ll n,d[233];
    
    inline int g(ll x){
    	return add(ksm(k-1,x%P),(x&1)?ha-(k-1)%ha:(k-1)%ha);
    }
    
    void dfs(int x,ll y,ll phi){
    	if(x==num){ if(y!=n) ADD(ans,phi%ha*(ll)g(n/y)%ha); return;}
    	dfs(x+1,y,phi);
    	
    	y*=d[x+1],phi*=d[x+1]-1;
    	for(int u=1;u<=c[x+1];u++,y*=d[x+1],phi*=d[x+1]) dfs(x+1,y,phi);
    }
    
    inline void solve(){
    	if(n==1){ ans=k%ha; return;}
    	
    	ll u=n;
    	
    	for(int i=2;i*(ll)i<=n;i++) if(!(u%i)){
    		c[++num]=0,d[num]=i;
    		while(!(u%i)) u/=i,c[num]++;
    	}
    	
    	if(u!=1) c[++num]=1,d[num]=u;
    	
    	dfs(0,1,1);
    	
    	ans=ans*(ll)ksm(n%ha,ha-2)%ha;
    }
    
    int main(){
    	freopen("necklace.in","r",stdin);
    	freopen("necklace.out","w",stdout);
    	
    	scanf("%d",&T);
    	while(T--){
    		scanf("%lld%d",&n,&k),ans=0;
    		num=0,solve(),printf("%d
    ",ans);
    	}
    	
    	return 0;
    }
    

      

  • 相关阅读:
    ORACLE触发器详解
    论文笔记 Interpreting Black-Box Classifiers Using Instance-Level Visual Explanations
    Popush迭代2个人总结
    Popush迭代1个人总结
    Popush第5次会议记录
    Xv6代码阅读报告之进程调度
    Popush源代码学习报告
    Popush 第二次小组会议记录及分工
    Popush 用户故事
    “老衲印象”开发团队章程
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9108906.html
Copyright © 2011-2022 走看看