HDU 3441 Rotation
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相关推荐
- 【HDU】3441 Rotation
题意:给出A和C(1<=A,C<=10^9),所有满足B * B * K + 1 = A * A, (K >= 0)的B,构成边长为B的正方形,等角度的围绕在一个小正方形的周围.用C ...
- HDU 4708 Rotation Lock Puzzle(模拟)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4708 题目大意:给定一个方形矩阵,边长为3-10的奇数.每一圈的数字可以沿着顺时针方向和逆时针方向旋转 ...
- 解题报告 (五) Burnside引理和Polya定理
Burnside引理 笔者第一次看到Burnside引理那个公式的时候一头雾水,找了本组合数学的书一看,全是概念.后来慢慢从Polya定理开始,做了一些题总算理解了.本文将从最简单的例子出发,解释Bu ...
- HDU 1667 The Rotation Game
参考文章:http://blog.csdn.net/urecvbnkuhbh_54245df/article/details/5856756 The portal:http://acm.hdu.edu ...
- hdu 1667:The Rotation Game
题目可以看IDA*学习笔记-HDU1667 The Rotation Game_ex_voda的博客-CSDN博客 关于如何存储这个条状数组,我们开一个大的矩阵数组装下来就行了.当然,特殊坐标单独开两 ...
- 【搜索进阶】HDU 1667 The Rotation Game
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1667 IDA*的入门题目,状态过多容易超内存,正好体现了IDA*的优势,每次操作移动能使一个数字进入中 ...
- HDU 1667 The Rotation Game (A*迭代搜索)
题目大意:略 每次选择一个最大深度K,跑IDA* 估价函数H=8-中间8个格里出现次数最多的数的个数x,即把它填满这个数最少需要8-x次操作,如果dep+H>K,就跳出.. 深搜的时候暴力修改, ...
- hdu 1667 The Rotation Game(IDA*)
题目大意: 有一个井字形结构的图形,每条线上7个数字(1,2,3,),每次可以从八个方向将一条线上的数字循环移动1个距离,问经过最少几次什么操作,可以将图形中间的八个方块变成同一种数字. 解题思路: ...
- HUD 1043 Eight 八数码问题 A*算法 1667 The Rotation Game IDA*算法
先是这周是搜索的题,网站:http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=6041 主要内容是BFS,A*,IDA*,还有一道K短路的,.. ...
最新文章
- 数据库服务器 之 PostgreSQL数据库的日常维护工作
- 关于BeginPaint和WM_ERASEBKGND
- 如何修改html页眉页脚,如何使用标准页眉和页脚修改/更新一组html文件
- python学成什么样可以找工作-Python 爬虫学到什么样就可以找工作了?
- shrio初体验(2)Realm
- 入门Java菜鸟,JDK和Eclipse的安装一定要知道
- c语言整数与平均值,编写求一组整数的和与平均值的程序
- VLAN与子网划分区别
- 上下级平台之间数据同步方案_Alluxio与底层存储系统之间的元数据同步机制
- linux自动归档,Linux之归档、压缩
- 为什么有的工人喜欢午餐和晚餐配着一瓶啤酒?
- 吴昊品游戏核心算法 Round 18 —— 吴昊教你玩Zen Puzzle Garden
- [译文]Domain Driven Design Reference(六)—— 提炼战略设计
- linux文件权限651,Linux基础之文件权限详解
- Geek Uninstaller
- 法律对合伙企业债务承担方式的规定
- 迁移学习癌医学影像检测
- OC的单例模式的实现
- 深入line-height,中线,基线,底线,顶线
- zabbix代理服务器配置
热门文章
- 引入dubbo项目接口_dubbo接口调用过程中,部分字段值丢失
- 删除还原点 oracle,oracle 还原点(restore point)
- java学到什么程度安卓_自学Android到什么程度才能找到工作?
- Layui--颜色选择器layui.colorpicker
- 服务器系统事件报错4103,IIS信息服务器排错指导
- 中one_Chair_One 一号椅
- Oracle主库、备库redo日志管理
- php zhxing iptables,Linux iptables 扩展 ipset 使用教程
- putty 32位_了解linux系统远程操作软件,putty的安装过程!
- java报505_Java调用URL错误,报505