UVA - 10294 Arif in Dhaka (First Love Part 2)(等价类计数)

题意:

项链和手环都是若干珠子构成的环形首饰,手环可以翻转,项链不行,例如下图中的两个手环是相同的。不论是手环还是项链,在旋转之后一样则视为相同。
在这里插入图片描述

给定n和t,输出用t种颜色的珠子(每种无限个),制作成n个珠子组成的项链和手环个数。

数据范围:n<=50,t<=10

解法:

显然是等价类计数问题
题目存在两种置换:翻转和旋转

项链只有旋转置换
手环有旋转和翻转两种置换

将珠子标号为0-(n-1)
旋转:
考虑珠子间隔为i的循环,那么每个循环中珠子数量为n/gcd(n,i),共有gcd(n,i)个循环。
珠子数量为n/gcd(n,i)的证明:循环中珠子标号为0,i,2i,3i…(t-1)i%n。因为是循环,那么t i%n=0,t i=k n,k取所有满足条件的k中的最小值。当ti=lcm(i,n)的时候,t和k为最小值,此时ti=lcm(i,n)->t=lcm(i,n)/i=i n/gcd(i,n)/i=n/gcd(i,n)。
那么不动点的数量为tgcd(i,n)
对i=0到n-1的每个i的不动点求和即可,即sum(tgcd(i,n))。

翻转:
1.n为奇数时,有n个对称轴,每个对称轴左右两边的对称点是一个循环,一共(n-1)/2个循环,对称轴上有一个点单独是一个循环,那么一共(n+1)/2个循环。那么不动点总数量为nt(n+1)/2
2.n为偶数时,对称轴有两种,一种对称轴穿过珠子,一种不穿。穿过珠子的对称轴有n/2条,每个对称轴有(n-2)/2个对称循环和2个单点循环,循环数为(n+2)/2。不穿过珠子的对称轴有n/2条,每个对称轴有n/2个循环。综上得不动点的总数量为n/2(t(n+2)/2+tn/2)

计算出不动点总数,根据Polya定理计算平均值就是答案。
项链除以n,手环除以2n

code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=2e5+5;
int n,t;
int ppow(int a,int b){
    int ans=1;
    while(b){
        if(b&1)ans=ans*a;
        a=a*a;
        b>>=1;
    }
    return ans;
}
signed main(){
    while(cin>>n>>t){
        //旋转
        int sum1=0;
        for(int i=1;i<=n;i++){
            sum1+=ppow(t,__gcd(n,i));
        }
        //翻转
        int sum2=0;
        if(n%2){
            sum2+=n*ppow(t,(n+1)/2);
        }else{
            sum2+=n/2*(ppow(t,(n+2)/2)+ppow(t,n/2));
        }
        //输出
        cout<<sum1/n<<' '<<(sum1+sum2)/(2*n)<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/107437007