1. 程式人生 > >Sgu294He's Circles

Sgu294He's Circles

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