置换小结(群论)

一、相关概念

1、置换:如果记A[i]为置换A的第i个元素,那么对一个排列进行置换A这个操作,表示将原先第i个位置上的数字挪到第A[i]个位置。如(2,3,1)表示第一个位置上的数字移动到第二个位置上,第二个位置上的数字移动到第三个位置上,第三个位置上的数字移动到第一个位置上。

2、置换乘法:依次进行两个置换所得到的结果。注意:乘法满足结合律,不满足交换律。如(2,3,1)*(1,3,2)=(3,2,1)

3、置换分解:将置换第i个位置上的数字挪到第A[i]个位置表示成i->A[i]的图,则一个置换可以分解为多个环,每个置换都写成不相交循环的乘积。如:(1,3,2)=(1)(3,2)其中(1)与(3,2)分别为一个环。

4、等价类计数问题:题目中会定义一类等价关系,满足等价关系的元素被看成同一类,只统计一次。

5、置换的不动点:如果一个值经过置换后位置不变,则称这个值(位置)为这个置换的不动点。如:(1,3,2)的不动点为1。

6、burnside引理: 等价类计数问题中不同本质的方案数等于每个置换的不动点个数之和。

7、polay定理:用于快速求每个置换的不动点个数。将置换f分解成m(f)个循环的乘积,并假设涂k种颜色的话,所有置换的k^m(f)的平均值就是等价类的个数。

二、例题

1、UVA-10294

题意:n颗珠子t种颜色,求有多少种项链和手镯,项链不可以翻转,手镯可以翻转。

题解:对于旋转操作,我们可以旋转0,1,2,...,n-1个珠子,每个旋转对应的置换群的循环节个数为gcd(i,n),现涂t种颜色,所以所有置换循环节个数的和为sum(t^gcd(i,n))。

对于翻转操作,如果n为奇数,则其中一个点为不动点,其他点分两个为一个循环节,形如(1)(2,3)(4,5)...(n-1,n),所以每个置换的循环节个数为n/2+1。共有n个置换,所以,所有置换循环节个数的和为n*t^(n/2+1)。

如果n为偶数,则其中两个点为不动点或者没有不动点,形如(1)(2)(3,4)...(n-1,n)或(1,2)(3,4)...(n-1,n),所以每个置换的循环节个数为n/2+1或n/2。共有n个置换,但循环节会重复。所以,所有置换的和为(n/2)*(t^(n/2+1)+t^(n/2))。

因为对于手镯来说可以旋转也可以翻转,所以一共有2*n个置换,所以等价类个数=(旋转置换循环节个数+翻转置换循环节个数)/(2*n)。

对于项链来说只能旋转,所以一共有n个置换,所以等价类个数=旋转置换循环节个数/n。

#include <bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int maxn = 1e5 + 10;
const int maxm = 1e6 + 10;
const int mod  = 1e9 + 7;
const int inf = 2e9 + 7;
const double  dinf = 10000000007.0;

ll p[maxn];

int main() {
#ifdef LOCAL
    freopen("input.in", "r", stdin);
//    freopen("out.in", "w", stdout);
#endif // LOCAL
    int n,t;
    while(~scanf("%d%d",&n,&t)){
        p[0] = 1LL;
        for(int i = 1; i <= n; i++) p[i] = (ll)t * p[i - 1];
        ll a = 0;
        for(int i = 1; i <= n; i++) a += p[__gcd(i,n)];
        ll b = 0;
        if(n % 2 == 1) b = (ll)n * p[n/2+1];
        else b = (ll)n/2 * (p[n/2] + p[n/2+1]);
        printf("%lld %lld\n",a / (ll)n, (a + b) / (2LL * n));
    }
    return 0;
}

 

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值