两种操作:
1.沿着中心旋转,总共s个,转过i个,循环个数是s*i/lcm(s,i) = gcd(i,s)
2.沿着轴翻转,注意本身在操作中不变的元素会对循环个数有贡献
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <map> #include <set> #include <algorithm> #include <ctime> #include <vector> #include <string> #include <stack> #include <queue> using namespace std; #define mod 100000007 #define ll long long ll gcd(ll a,ll b) { if(b==0) return a; return gcd(b,a%b); } ll p[50]; int main () { ll c,s,ans; while(scanf("%lld%lld",&c,&s)!=EOF) { if(c==0 && s==0) break; if(c==0 || s==0) { printf("0\n"); continue; } ans=0; p[0]=1; for(int i=1;i<=32;++i) p[i]=p[i-1]*c; for(ll i=1;i<=s;++i) ans+=p[gcd(i,s)]; if(s%2) ans+=s*p[(s-1)/2+1]; else ans+=s/2*p[s/2]+s/2*p[s/2+1]; printf("%lld\n",ans/2/s); } return 0; }