Sgu294He's Circles

Description
有一个长度为N的环,上面写着’X’和’E’,问本质不同的环有多少种。(N不超过200000)。

Input
The input file contains a single integer 1 <= n <= 200000.

Output
Output a single integer --- the number circular strings of length n.

Sample Input
3

Sample Output
4


polya裸题,和[POJ2154]Color一样,只是需要带个高精度罢了,只有两种颜色,不用取模

/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline int read(){
	int x=0,f=1;char ch=getchar();
	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
	return x*f;
}
inline void print(int x){
	if (x>=10)     print(x/10);
	putchar(x%10+'0');
}
const int N=2e5;
const int base=1e4;
const int digit=4;
const int maxn=1e2;
struct Bignum{
	int len,v[maxn];
	Bignum(){len=1,memset(v,0,sizeof(v));}
	void init(){v[0]=1;}
	void write(){
		printf("%d",v[len-1]);
		for (int i=len-2;~i;i--)	printf("%0*d",digit,v[i]);
		putchar('\n');
	}
};
int prime[N+10],phi[N+10];
bool inprime[N+10];
int tot;
void prepare(){
	phi[1]=1;
	for (int i=2;i<=N;i++){
		if (!inprime[i])	prime[++tot]=i,phi[i]=i-1;
		for (int j=1;j<=tot&&prime[j]*i<=N;j++){
			inprime[prime[j]*i]=1;
			if (i%prime[j]==0)	phi[i*prime[j]]=phi[i]*prime[j];
			else	phi[i*prime[j]]=phi[i]*(prime[j]-1);
		}
	}
}
Bignum operator +(const Bignum &x,const Bignum &y){
	Bignum z;
	z.len=max(x.len,y.len);
	for (int i=0;i<=z.len;i++)	z.v[i]+=x.v[i]+y.v[i],z.v[i+1]+=z.v[i]/base,z.v[i]%=base;
	while (z.v[z.len])	z.v[z.len+1]+=z.v[z.len]/base,z.v[z.len]%=base,z.len++;
	return z;
}
Bignum operator *(const Bignum &x,const Bignum &y){
	Bignum z;
	z.len=x.len+y.len;
	for (int i=0;i<=x.len;i++)
		for (int j=0;j<=y.len;j++)
			z.v[i+j]+=x.v[i]*y.v[j],z.v[i+j+1]+=z.v[i+j]/base,z.v[i+j]%=base;
	while (z.len!=1&&!z.v[z.len])	z.len--;z.len++;
	while (z.v[z.len])	z.v[z.len+1]+=z.v[z.len]/base,z.v[z.len]%=base,z.len++;
	return z;
}
Bignum operator /(Bignum &x,int y){
	for (int i=x.len;~i;i--)	x.v[i-1]+=x.v[i]%y*base,x.v[i]/=y;
	while (x.len!=1&&!x.v[x.len])	x.len--;
	while (x.v[x.len])	x.v[x.len+1]+=x.v[x.len]/base,x.v[x.len]%=base,x.len++;
	return x;
}
Bignum mlt(Bignum a,int b){
	Bignum res;res.init();
	for (;b;b>>=1,a=a*a)	if (b&1)	res=res*a;
	return res;
}
Bignum change(int x){
	Bignum z;
	while (x){
		z.v[z.len-1]=x%base;
		z.len++;
		x/=base;
	}
	while (z.len!=1&&!z.v[z.len])	z.len--;
	while (z.v[z.len])	z.v[z.len+1]+=z.v[z.len]/base,z.v[z.len]%=base,z.len++;
	return z;
}
int main(){
	prepare();
	int n=read();
	Bignum Two,Ans;
	Two.v[0]=2;
	for (int i=1;i*i<=n;i++){
		if (n%i)	continue;
		int j=n/i;
		Ans=Ans+mlt(Two,i)*change(phi[j]);
		if (i!=j)	Ans=Ans+mlt(Two,j)*change(phi[i]);
	}
	Ans=Ans/n;
	Ans.write();
	return 0;
}
posted @ 2018-03-07 20:19  Wolfycz  阅读(247)  评论(0编辑  收藏  举报