Sgu294He's Circles
阿新 • • 發佈:2018-03-07
getchar con blog ems spa ger amp rcu ons
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裸題,和pku2154 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; }
Sgu294He's Circles