题目链接:http://vjudge.net/problem/viewProblem.action?id=11117
就是利用每种等价情形算出置换节之后算组合数
#include <stdio.h> #include <cstring> #include <cstdlib> #include <algorithm> #include <cmath>using namespace std; #define lson o<<1 #define rson o<<1|1 #define max(a,b) (a)>(b)?(a):(b) #define min(a,b) (a)<(b)?(a):(b) #define INF 200000000typedef long long ll; ll qpow(ll a,int k){ll ans=1;while(k>0){if(k&1)ans*=a;a*=a;k>>=1;}return ans; } int gcd(int a,int b){if(a==0)return b;return gcd(b%a,a); } ll rotation(int n){ll rot=3;for(int i=2;i<=n;i++){rot+=qpow(3LL,gcd(i,n));}return rot; } ll reflection(int n){ll ref=0;if(n&1){int cir=n/2+1;ref=qpow(3LL,cir)*n;}else{ref=(ll)(n/2)*qpow(3LL,n/2);ref+=(ll)(n/2)*qpow(3LL,1+n/2);}return ref; } int main(){int n;while(~scanf("%d",&n) && n+1){ll ans;if(!n)ans=0;else ans=(rotation(n)+reflection(n))/(2*n);printf("%I64d\n",ans);}return 0; }