HDU_3441

首先声明一点,对于A=1的情况最好特判,因为有些处理措施对于A=1的情况会造成死循环从而TLE。

思路其实还算比较直接,但是处理起来比较繁琐。由于小正方形旋转同构,那么对于一个特定的B我们至少要先求得有多少本质不同的小正方形,这一点可以用polya定理计算出来。

接着,对于一组特定的B、K, 拼成的这个图形依然循环同构,但我们之前已经算出了有多少本质不同的小正方形,于是可以将这些本质不同的小正方形看成不同的颜色,于是再用一次polya定理就可以计算出结果。而中间那个单位正方形的颜色是无所谓的,所以结果要乘以C,这样就得到了一组B、K对应的结果。

那么剩下的问题就是如可去确定有多少组B、K了。将原表达式变形之后可以得到K=(A-1)*(A+1)/(B*B),这时就会发现无论是B还是K,都是由A-1和A+1的素因子组合而成的,因此我们可以将这些素因子再单独放到一个表中,然后就可以枚举出每一组B、K了。同时,在计算K的某个约数的欧拉函数时我们还要用到这个新的素数表。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MOD 1000000007
#define MAXD 40010
using namespace std;
int isprime[MAXD], prime[MAXD], P, p[MAXD], pn;
long long A, C, K, ANS, T;
void exgcd(long long a, long long b, long long &x, long long &y)
{if(b == 0)x = 1, y = 0;elseexgcd(b, a % b, y, x), y -= x * (a / b);
}
long long powmod(long long a, long long n)
{long long ans = 1;while(n){if(n & 1)ans = ans * a % MOD;n >>= 1;a = a * a % MOD;}return ans;
}
void prepare()
{int i, j, k = 40000;memset(isprime, -1, sizeof(isprime));P = 0;for(i = 2; i <= k; i ++)if(isprime[i]){prime[P ++] = i;for(j = i * i; j <= k; j += i)isprime[j] = 0;}
}
long long block(long long n, long long c)
{long long ans, x, y;ans = powmod(c, n * n);ans = (ans + 2 * powmod(c, n * n / 4 + (n & 1))) % MOD;ans = (ans + powmod(c, n * n / 2 + (n & 1))) % MOD;exgcd(4, MOD, x, y);x = (x % MOD + MOD) % MOD;ans = ans * x % MOD;return ans;
}
long long euler(long long n)
{int i;long long ans = n;for(i = 0; i < pn; i ++)if(n % p[i] == 0)ans = ans / p[i] * (p[i] - 1);return ans;
}
long long prepareBK()
{int i, j, nx, ny, x, y, cnt;long long N = 1;nx = x = A - 1, ny = y = A + 1;pn = 0;for(i = 0; i < P && prime[i] * prime[i] <= ny; i ++){cnt = 0;if(x % prime[i] == 0 || y % prime[i] == 0)p[pn ++] = prime[i];while(x % prime[i] == 0)++ cnt, x /= prime[i];while(y % prime[i] == 0)++ cnt, y /= prime[i];for(j = 0, cnt /= 2; j < cnt; j ++)N *= prime[i];}if(x > y)i = x, x = y, y = i;if(x > 1)p[pn ++] = x;if(y > 1)p[pn ++] = y;if(x == y)N *= x;return N;
}
void dfs(int cur, long long R, long long x, long long &c)
{int i, cnt = 0;long long t = 1;if(cur == pn){long long ans, n, x, y;n = euler(K / R) % MOD;T = (T + n * powmod(c, R)) % MOD;return ;}while(x % p[cur] == 0)x /= p[cur], ++ cnt;for(i = 0; i <= cnt; i ++){dfs(cur + 1, R * t, x, c);t *= p[cur];}
}
void findB(int cur, long long B, long long x)
{int i, cnt = 0;long long t = 1;if(cur == pn){long long n, x, y, c;c = block(B, C);K = (A * A - 1) / (B * B);T = 0;dfs(0, 1, K, c);exgcd(K, MOD, x, y);x = (x % MOD + MOD) % MOD;T = (T * x) % MOD;ANS = (ANS + T * C) % MOD;return ;}while(x % p[cur] == 0)++ cnt, x /= p[cur];for(i = 0; i <= cnt; i ++){findB(cur + 1, B * t, x);t *= p[cur];}
}
void solve()
{ANS = 0;findB(0, 1, prepareBK());printf("%I64d\n", ANS);
}
int main()
{int t, tt;prepare();scanf("%d", &t);for(tt = 0; tt < t; tt ++){printf("Case %d: ", tt + 1);scanf("%I64d%I64d", &A, &C);if(A == 1)printf("%I64d\n", C);elsesolve();}return 0;
}

HDU 3441 Rotation相关推荐

  1. 【HDU】3441 Rotation

    题意:给出A和C(1<=A,C<=10^9),所有满足B * B * K + 1 = A * A, (K >= 0)的B,构成边长为B的正方形,等角度的围绕在一个小正方形的周围.用C ...

  2. HDU 4708 Rotation Lock Puzzle(模拟)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4708 题目大意:给定一个方形矩阵,边长为3-10的奇数.每一圈的数字可以沿着顺时针方向和逆时针方向旋转 ...

  3. 解题报告 (五) Burnside引理和Polya定理

    Burnside引理 笔者第一次看到Burnside引理那个公式的时候一头雾水,找了本组合数学的书一看,全是概念.后来慢慢从Polya定理开始,做了一些题总算理解了.本文将从最简单的例子出发,解释Bu ...

  4. HDU 1667 The Rotation Game

    参考文章:http://blog.csdn.net/urecvbnkuhbh_54245df/article/details/5856756 The portal:http://acm.hdu.edu ...

  5. hdu 1667:The Rotation Game

    题目可以看IDA*学习笔记-HDU1667 The Rotation Game_ex_voda的博客-CSDN博客 关于如何存储这个条状数组,我们开一个大的矩阵数组装下来就行了.当然,特殊坐标单独开两 ...

  6. 【搜索进阶】HDU 1667 The Rotation Game

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1667 IDA*的入门题目,状态过多容易超内存,正好体现了IDA*的优势,每次操作移动能使一个数字进入中 ...

  7. HDU 1667 The Rotation Game (A*迭代搜索)

    题目大意:略 每次选择一个最大深度K,跑IDA* 估价函数H=8-中间8个格里出现次数最多的数的个数x,即把它填满这个数最少需要8-x次操作,如果dep+H>K,就跳出.. 深搜的时候暴力修改, ...

  8. hdu 1667 The Rotation Game(IDA*)

    题目大意: 有一个井字形结构的图形,每条线上7个数字(1,2,3,),每次可以从八个方向将一条线上的数字循环移动1个距离,问经过最少几次什么操作,可以将图形中间的八个方块变成同一种数字. 解题思路: ...

  9. HUD 1043 Eight 八数码问题 A*算法 1667 The Rotation Game IDA*算法

    先是这周是搜索的题,网站:http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=6041 主要内容是BFS,A*,IDA*,还有一道K短路的,.. ...

最新文章

  1. 数据库服务器 之 PostgreSQL数据库的日常维护工作
  2. 关于BeginPaint和WM_ERASEBKGND
  3. 如何修改html页眉页脚,如何使用标准页眉和页脚修改/更新一组html文件
  4. python学成什么样可以找工作-Python 爬虫学到什么样就可以找工作了?
  5. shrio初体验(2)Realm
  6. 入门Java菜鸟,JDK和Eclipse的安装一定要知道
  7. c语言整数与平均值,编写求一组整数的和与平均值的程序
  8. VLAN与子网划分区别
  9. 上下级平台之间数据同步方案_Alluxio与底层存储系统之间的元数据同步机制
  10. linux自动归档,Linux之归档、压缩
  11. 为什么有的工人喜欢午餐和晚餐配着一瓶啤酒?
  12. 吴昊品游戏核心算法 Round 18 —— 吴昊教你玩Zen Puzzle Garden
  13. [译文]Domain Driven Design Reference(六)—— 提炼战略设计
  14. linux文件权限651,Linux基础之文件权限详解
  15. Geek Uninstaller
  16. 法律对合伙企业债务承担方式的规定
  17. 迁移学习癌医学影像检测
  18. OC的单例模式的实现
  19. 深入line-height,中线,基线,底线,顶线
  20. zabbix代理服务器配置

热门文章

  1. 引入dubbo项目接口_dubbo接口调用过程中,部分字段值丢失
  2. 删除还原点 oracle,oracle 还原点(restore point)
  3. java学到什么程度安卓_自学Android到什么程度才能找到工作?
  4. Layui--颜色选择器layui.colorpicker
  5. 服务器系统事件报错4103,IIS信息服务器排错指导
  6. 中one_Chair_One 一号椅
  7. Oracle主库、备库redo日志管理
  8. php zhxing iptables,Linux iptables 扩展 ipset 使用教程
  9. putty 32位_了解linux系统远程操作软件,putty的安装过程!
  10. java报505_Java调用URL错误,报505