总的来说,这题要2次用到polya定理。

由题目条件A*A=B*B+1,变形为(A-1)*(A+1)=K*B*B;

分别分解A-1和A+1的质因数,在合并在一起。

第一步:搜索B,对B*B的正方形涂色,基本的polya定理搞定,即C^(B*B)+C^((B*B+1)/2)+2*C^((B*B+3)/4).

第二步:搜索K,在A-1和A+1的因子中搜索,这样不会超时,在用polya定理,最后在结果上乘C就可以了……

 

  1 #include<iostream>
2 #include<stdio.h>
3 #include<algorithm>
4 #include<iomanip>
5 #include<cmath>
6 #include<string>
7 #include<vector>
8 using namespace std;
9 const long mod=1000000007;
10 int prime[40003],m,fac[1000][2],flen;
11 vector<int> v;
12 bool f[40003];
13 __int64 A,C,ans,ret_A,inverse_4,inverse_k;
14 void init()
15 {
16 __int64 i,j;
17 m=0;
18 for(i=2;i<=40000;i++)
19 if(f[i]==0)
20 {
21 prime[m++]=i;
22 for(j=i*i;j<=40000;j+=i)
23 f[j]=1;
24 }
25 }
26 __int64 extend_gcd(__int64 a,__int64 b,__int64 &x,__int64 &y)
27 {
28 __int64 d;
29 if(b==0)
30 {
31 x=1;y=0;
32 return a;
33 }
34 else
35 {
36 d=extend_gcd(b,a%b,x,y);
37 __int64 temp=x;
38 x=y;
39 y=temp-a/b*y;
40 }
41 return d;
42 }
43 __int64 pows(__int64 a,__int64 b)
44 {
45 __int64 ans=1;
46 a%=mod;
47 while(b)
48 {
49 if(b&1) ans=(ans*a)%mod;
50 b>>=1;
51 a=(a*a)%mod;
52 }
53 return ans%mod;
54 }
55 void factor(__int64 n)
56 {
57 int i;
58 for(i=0;i<m&&prime[i]*prime[i]<=n;i++)
59 while(n%prime[i]==0)
60 {
61 v.push_back(prime[i]);
62 n/=prime[i];
63 }
64 if(n>1) v.push_back(n);
65 }
66 void combine()
67 {
68 sort(v.begin(),v.end());
69 int i,j;
70 flen=0;
71 fac[flen][0]=v[0];
72 fac[flen++][1]=1;
73 for(i=1;i<v.size();i++)
74 {
75 if(v[i]==fac[flen-1][0])
76 fac[flen-1][1]++;
77 else
78 {
79 fac[flen][0]=v[i];
80 fac[flen++][1]=1;
81 }
82 }
83 }
84 __int64 inverse(__int64 a)
85 {
86 __int64 x,y;
87 extend_gcd(a,mod,x,y);
88 return (x%mod+mod)%mod;
89 }
90 __int64 euler(__int64 n)
91 {
92 int i;
93 __int64 ans=1;
94 for(i=0;i<flen&&fac[i][0]*fac[i][0]<=n;i++)
95 {
96 if(n%fac[i][0]==0)
97 {
98 ans*=fac[i][0]-1;
99 n/=fac[i][0];
100 while(n%fac[i][0]==0)
101 {
102 ans*=fac[i][0];
103 n/=fac[i][0];
104 }
105 }
106 }
107 if(n>1) ans*=n-1;
108 return ans%mod;
109 }
110 void dfs(__int64 d,__int64 num,__int64 cnt_B,__int64 k)
111 {
112 if(d>=flen)
113 {
114 ret_A=(ret_A+pows(cnt_B,k/num)*euler(num)%mod)%mod;
115 return ;
116 }
117 for(int i=0;i<=fac[d][1];i++)
118 {
119 dfs(d+1,num,cnt_B,k);
120 num*=fac[d][0];
121 }
122 }
123 __int64 get_A(__int64 k,__int64 cnt_B)
124 {
125 ret_A=0;
126 dfs(0,1,cnt_B,k);
127 return ((ret_A*inverse_k)%mod)*C%mod;
128 }
129 __int64 get_B(__int64 n)
130 {
131 __int64 ans=pows(C,n*n);
132 ans=(ans+pows(C,(n*n+1)/2)%mod)%mod;
133 ans=(ans+2*pows(C,(n*n+3)/4)%mod)%mod;
134 return (ans*inverse_4)%mod;
135 }
136 //枚举B
137 //d表示深度,num表示枚举因子的大小
138 void dfsB(__int64 d,__int64 num)
139 {
140 if(d>=flen)
141 {
142 __int64 cnt_B=get_B(num);
143 __int64 k=(A*A-1)/num/num;
144 inverse_k=inverse(k);
145 ans=(ans+get_A(k,cnt_B))%mod;
146 return ;
147 }
148 int temp=fac[d][1];
149 for(int i=0;i<=temp;i+=2,fac[d][1]-=2)
150 {
151 dfsB(d+1,num);
152 num*=fac[d][0];
153 }
154 fac[d][1]=temp;
155 }
156 __int64 solve()
157 {
158 v.clear();
159 factor(A-1);
160 factor(A+1);
161 combine();
162 ans=0;
163 dfsB(0,1);
164 return ans;
165 }
166 int main()
167 {
168 init();
169 int t,k=0;
170 inverse_4=inverse(4);
171 cin>>t;
172 while(t--)
173 {
174 scanf("%I64d%I64d",&A,&C);
175 if(A==1)
176 printf("Case %d: %I64d\n",++k,C);
177 else printf("Case %d: %I64d\n",++k,solve());
178 }
179 return 0;
180 }

 

 

 

hdu 3441 Rotation的更多相关文章

  1. HDU 4708:Rotation Lock Puzzle

    Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  2. HDU 4708 Rotation Lock Puzzle(模拟)

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

  3. HDU 4708 Rotation Lock Puzzle (简单题)

    Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  4. hdu 4708 Rotation Lock Puzzle 2013年ICPC热身赛A题 旋转矩阵

    题意:给出一个n*n的矩阵,旋转每一圈数字,求出对角线可能的最大值,以及转到最大时的最小距离. 只要分析每一层就可以了,本来想用地址传递二维数组,发现行不通,改了一下就行了. 这里有个坑,比如: 1 ...

  5. IDA*、操作打表、并行处理-The Rotation Game HDU - 1667

    万恶之源 优秀题解 用文字终究难以穷尽代码的思想 思路 每次操作都有八种选择,相当于一棵每次延申八个子节点的搜索树,故搜索应该是一种方法.而这题要求求最少步数,我们就可以想到可以试试迭代加深搜索(但其 ...

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

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

  7. hdu 1667 The Rotation Game ( IDA* )

    题目大意: 给你一个“井”子状的board,对称的由24个方块组成,每个方块上有123三个数字中的一个.给你初始状态,共有八种变换方式,求字典序最小的最短的的变换路径使得,board中间的八个方块上数 ...

  8. HDU 1817Necklace of Beads(置换+Polya计数)

    Necklace of Beads Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  9. hduoj 4708 Rotation Lock Puzzle 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4708 Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/O ...

随机推荐

  1. 【风马一族_xml】xml编程

    xml编程:利用java程序支增删改查(CRUD)XML中的数据 解析思想: dom解析 sax解析 基于这两种解析思想市面上就有了很多的解析api sun jaxp (比较弱)既有dom方式也有sa ...

  2. 水仙花数 java 实现

    题目描述: 春天是鲜花的季节,水仙花就是其中最迷人的代表,数学上有个水仙花数,他是这样定义的:“水仙花数”是指一个三位数,它的各位数字的立方和等于其本身,比如:153=1^3+5^3+3^3.现在要求 ...

  3. <Linux下echo指令>

    echo这个命令我们最常见的还是在shell脚本中的使用,if语句,for语句,case语句....这些都不是对echo命令的全面了解.下面还有很多其他echo的参数: 来自本人的日常生活,和对资料查 ...

  4. js设计模式(9)---代理模式

    0.前言 KG.PP被交易到了布鲁克林篮网,我的心情很复杂,一方面为他们不能终老celtics感到惋惜,另一方面为他们能够再次冲击总冠军感到高兴.从07年以来,作为一个铁杆celtics球迷,他们给我 ...

  5. 为 WordPress 标签添加 rel="nofollow" 属性

    WordPress 标签默认并无 rel="nofollow" 属性.rel="nofollow" 属性的作用是:告诉搜索引擎,无需追踪目标页,禁止蜘蛛爬行和传 ...

  6. PHP学习之数组的定义和填充

    数组就是把一组数据按顺序放在一起.PHP的数组和其它的语言数组有一点点不同:第一,保存的数据是可以是任何类型的:第二,数组的索引可以是数字,也可以是字符串. PHP的数组,说白了,就是关联数据每一条数 ...

  7. js获取location.href的参数实例代码

    本文为大家介绍下js如何获取location.href的参数,需要注意的是去掉参数里最开头的?号,具体实现如下,有需要的朋友可以参考下,希望对大家有所帮助 window.location.search ...

  8. ORACLE AWR 和 ASH

    一.关于ASH 我们都知道,用户在 ORACLE 数据库中执行操作时,必然要创建相应的连接和会话, 其中,所有当前的会话信息都保存在动态性能视图 V$SESSION 中,通过该视图,DBA 可 以查看 ...

  9. 1093. Count PAT's (25)

    The string APPAPT contains two PAT's as substrings. The first one is formed by the 2nd, the 4th, and ...

  10. cadence 机械孔的制作

    在平时画PCB的时候,会用到安装孔,好多人就是找个过孔,在原理图中连接GND,这样使用也可以,下面介绍一种正经机械孔的制作方法(自己摸索的),制作一个孔径为3mm的安装孔. 1 打开pad desig ...