和上题一样,但K较大,不能直接用矩阵来写。这个矩阵必定是这个形式的。

0 1 1 1

1 0 1 1

1 1 0 1

1 1 1 0

分成对角线上元素B与非对角线上元素A

k: 1 2 3 4 ...

A: 1 2 7 20...

B: 0 3 6 21...

按上题经验,我们可以知道,B才是要求的。那么

Bn=(k-1)An-1

An=(k-2)An-1+Bn-1

于是可以得到

An=(k-2)An-1+(k-1)*An-2.这里就可以使用到矩阵连乘了。

可以通过A求得B。注意,这里能用的只能是K-1种颜色,因为中间一种颜色已不可用。于是,按上题同样的思路即可。

PS:今天不知为什么,内心特别烦闷。这道题的思路,昨天就想到的,本以为留着今天来写。可是,没想到,一点心情也没有。。。以后也不做这种蠢事,一定要一有思路,马上就写。。。。

贴个别人的代码吧。。(他是求出了Bn的表达式的,但我找不出来)

#include<cstdio>
#include<cstring>
#include<vector>
#define P 1000000007
#define MAXM 2
#define MAXN 32000
typedef long long LL;
using namespace std;
bool p[MAXN];
vector<int> factor;
vector<int> prime;
struct Matrix {
LL mat[MAXM][MAXM];
void Zero() {
memset(mat, 0, sizeof(mat));
}
void Unit() {
Zero();
mat[0][0] = mat[1][1] = 1;
}
void Build(int k) {
Zero();
mat[0][1] = 1;
mat[0][0] = k - 2;
mat[1][0] = k - 1;
}
};
Matrix operator *(Matrix &a, Matrix &b) {
int i, j, k;
Matrix tmp;
tmp.Zero();
for (i = 0; i < MAXM; i++) {
for (j = 0; j < MAXM; j++) {
for (k = 0; k < MAXM; k++)
tmp.mat[i][j] += a.mat[i][k] * b.mat[k][j];
tmp.mat[i][j] %= P;
}
}
return tmp;
}
Matrix operator ^(Matrix a, int k) {
Matrix tmp;
for (tmp.Unit(); k; k >>= 1) {
if (k & 1)
tmp = tmp * a;
a = a * a;
}
return tmp;
}
void Factor(int n) {
int i;
factor.clear();
for (i = 1; i * i < n; i++) {
if (n % i == 0) {
factor.push_back(i);
factor.push_back(n / i);
}
}
if (i * i == n)
factor.push_back(i);
}
LL ExtGcd(LL a, LL b, LL &x, LL &y) {
LL t, d;
if (b == 0) {
x = 1;
y = 0;
return a;
}
d = ExtGcd(b, a % b, x, y);
t = x;
x = y;
y = t - a / b * y;
return d;
}
LL InvMod(LL a, LL n) {
LL x, y;
ExtGcd(a, n, x, y);
return (x % n + n) % n;
}
int Count(int x) {
int res, i;
res = x;
for (i = 0; prime[i] * prime[i] <= x; i++) {
if (x % prime[i] == 0) {
res -= res / prime[i];
while (x % prime[i] == 0)
x /= prime[i];
}
}
if (x > 1)
res -= res / x;
return res;
}
LL F(int n, int k) {
LL res;
if (n == 1)
res = 0;
else if (n == 2)
res = (LL) k * (k - 1);
else if (n == 3)
res = (LL) k * (k - 1) % P * (k - 2);
else {
Matrix g;
g.Build(k);
g = g ^ (n - 3);
res = g.mat[0][0] * k % P * (k - 1) % P * (k - 2);
res += g.mat[1][0] * k % P * (k - 1);
}
return res % P;
}
LL Burnside(int n, int k) {
LL ans;
int i;
Factor(n);
for (i = ans = 0; i < (int) factor.size(); i++) {
ans += F(factor[i], k) * Count(n / factor[i]) % P;
if (ans >= P)
ans -= P;
}
return ans * InvMod(n, P) % P;
}
void Init() {
int i, j;
memset(p, true, sizeof(p));
for (i = 2; i < 180; i++) {
if (p[i]) {
for (j = i * i; j < MAXN; j += i)
p[j] = false;
}
}
prime.clear();
for (i = 2; i < MAXN; i++) {
if (p[i])
prime.push_back(i);
}
}
int main() {
int n, k;
Init();
while (~scanf("%d%d", &n, &k))
printf("%I64d\n", Burnside(n, k - 1) * k % P);
return 0;
}

  

HDU 2865的更多相关文章

  1. hdu 2865 Polya计数+(矩阵 or 找规律 求C)

    Birthday Toy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  2. HDU 2865 Birthday Toy [Polya 矩阵乘法]

    传送门 题意: 相邻珠子不能相同,旋转等价.$n$个珠子$k$中颜色,求方案数 首先中间珠子$k$种选择,$k--$如果没有相邻不同的限制,就和$POJ\ 2154$一样了$|C(f)|=k^{\#( ...

  3. HDU 2865 Birthday Toy

    题目链接 题意:n个小珠子组成的正n边形,中间有一个大珠子.有木棍相连的两个珠子不能有相同的颜色,旋转后相同视为相同的方案,求着色方案数. \(\\\) 先选定一种颜色放在中间,剩下的\(k-1\)种 ...

  4. HDU 5643 King's Game 打表

    King's Game 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5643 Description In order to remember hi ...

  5. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  7. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  8. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  9. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

随机推荐

  1. SQL-Oracle存储过程-循环A表,向B表插入数据

    --存储过程,查询A表,向B表插入数据 create or replace procedure prc_sg_sjtj_config(p_flag out varchar2) IS BEGIN FOR ...

  2. 【智能家居篇】wifi网络结构(上)

    转载请注明出处:http://blog.csdn.net/Righthek 谢谢! WIFI是什么.相信大家都知道,这里就不作说明了. 我们须要做的是深入了解其工作原理,包含软硬件.网络结构等.先说明 ...

  3. uva 10003 Cutting Sticks 【区间dp】

    题目:uva 10003 Cutting Sticks 题意:给出一根长度 l 的木棍,要截断从某些点,然后截断的花费是当前木棍的长度,求总的最小花费? 分析:典型的区间dp,事实上和石子归并是一样的 ...

  4. HDU 1171 Big Event in HDU(多重背包)

    Big Event in HDU Problem Description Nowadays, we all know that Computer College is the biggest depa ...

  5. Codeforces Round #168 (Div. 2)---A. Lights Out

    Lights Out time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  6. Geeks - Range Minimum Query RMQ范围最小值查询

    使用线段树预处理.能够使得查询RMQ时间效率在O(lgn). 线段树是记录某范围内的最小值. 标准的线段树应用. Geeks上仅仅有两道线段树的题目了.并且没有讲到pushUp和pushDown操作. ...

  7. java基础——各种变量你晕了不?

    java 中的变量大致分为 成员变量 和 局部变量 两大类. 成员变量:     在类体里面定义的变量称为成员变量.     假设该成员变量有 static keyword修饰.则该成员变量称为 静态 ...

  8. POJ 1252 DP

    题意:给你6个数.让你求出1~100范围内的数 最优情况下由这六个数加减几步得到. 输出平均值和最大值. 思路: 我就随便写了写,,,感觉自己的思路完全不对. 但是交上去 AC了!!! 我先当减法 不 ...

  9. Spark SQL 编程API入门系列之Spark SQL的作用与使用方式

    不多说,直接上干货! Spark程序中使用SparkSQL 轻松读取数据并使用SQL 查询,同时还能把这一过程和普通的Python/Java/Scala 程序代码结合在一起. CLI---Spark ...

  10. T7315 yyy矩阵折叠(长)

    题目背景 全场基本暴零 题目描述 输入输出格式 输入格式: 如图 输出格式: 如图 输入输出样例 输入样例#1: 2 2 1 -2 3 -4 输出样例#1: 4 输入样例#2: 2 5 1 -2 -3 ...