Uva10294 Arif in Dhaka (置换问题)
继续刘汝佳大白之旅,这次是北京站赛前学学数学问题。
虽然说比赛前临时抱佛脚通常意义不大,不过表示即使短时间内用不上,但是只要给自己一点比赛前的压力,确实学起来动力会足一些,即使被平时的各类大物实验,电工实验,计算机硬件实验以及素描忙的够呛。
扯回正题,此题需要知道的是置换群的概念,这点在刘汝佳的书中写的比较详细,此处不多做赘述。此处多说一句的是第二种手镯的情况。在下图中“左图顺时针转1个位置”和“右图顺时针旋转5个位置”是相同的,所以在最终结果处需要(ans1+ans2)/2。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef long long LL; int n, t; //int prime[] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47}; long long pow_num[55]; int main() { while(~scanf("%d%d", &n, &t) && n) { memset(pow_num, 0, sizeof(pow_num)); pow_num[0] = 1LL; for(int i = 1; i <= n; i++) { pow_num[i] = pow_num[i - 1] * (LL)t; } LL ans1 = 0LL, ans2 = 0LL; for(int i = 1; i <= n; i++) { ans1 += pow_num[__gcd(i, n)]; } if(n % 2 == 1) { ans2 = n * pow_num[n / 2 + 1]; } else { ans2 = n / 2 * pow_num[n / 2] + n / 2 * pow_num[(n - 2) / 2 + 2]; } cout<<ans1 / n<<" "<<(ans1 + ans2) / 2 / n<<endl; } return 0; }