LG4980 [テンプレート]ポリアの定理とBZOJ2026宝石記念貨幣

問題の意味

タイトル説明

$ N - $ポイント、シクロ$ N- $エッジを考えると、そこに$ N- $色は各頂点彩色のためのもの、そしてどのように多く尋ね異なる性質のプロトコルを染色、$ 10 ^ 9 + 7 $剰余への答えを

:この質問の異なる性質を注意してください、それが定義されているだけで、他の染色プロトコルと同じ回転を通過することができません

入出力フォーマット

入力フォーマット:

入力の最初の行のデータの$ T $、$ T $発現組

二行目、$線T $の合計、$ $整数各N-、示すようにタイトルを意味します。

出力フォーマット:

$線T CO $、染色プロトコル番号$ 10 $ ^ 7 + 9 MODの結果を表す各桁

サンプル入力と出力

入力サンプル#1: コピー
5 
1 
2 
3 
4 
5
出力サンプル#1: コピー
1 
3 
11 
70 
629

説明

$$ N \当量10 ^ 9 $$ T \当量10 ^ 3 $$

分析

固定小数点数は、第1式に行きます。運動サイクリング考えてみましょう\(I \)ビット置換、ビーズのサイクル数を。携帯電話番号が繰り返されるので、最大数がなければならないので、\(\ TEXTRM} {LCM(I、M)\) したがって、一回の周期であるビーズの数\(\ FRAC {\ TEXTRM} {LCM(I、M)} = {I} \ {N-FRAC} {N- \ GCD(I)} \) 合計だから、\(\ GCDは、(i、N )\) サイクル。したがって、固定小数点数\(N ^ {\ GCD( I、N)} \)

回答式だから、

\ [\ FRAC 1N \ sum_ {I = 0} ^ {N-1}のn ^ {\ GCD(I、N)} \\ = \ FRAC 1N \ sum_ {D | N} \ varphi(\ FRACのND)N ^ D \\ = \ sum_ {D | N} \ varphi(D)N ^ {\ FRAC ND-1} \]

私は約いくつかの数を達成することができないか、とにかく、最初のピースの数を知って、その後、どのくらいのオイラー関数の複雑さをカウントしない(O(\ SQRT {nが\ })\) 上限。\(2 ^ 3 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23 = 892 371 480 \) この数は約1024未満の数であり、\(\ SQRT {892 371 480} = 29872.587433 \)

int phi(int n){
    int re=n;
    for(int i=2;i*i<=n;++i)if(n%i==0){
        re=re/i*(i-1);
        while(n%i==0) n/=i;
    }
    if(n>1) re=re/n*(n-1);
    return re;
}
void Polya(){
    int n=read<int>(),ans=0;
    for(int i=1;i*i<=n;++i)if(n%i==0){
        ans=add(ans,mul(phi(i),fpow(n,n/i-1)));
        if(i*i!=n) ans=add(ans,mul(phi(n/i),fpow(n,i-1)));
    }
    printf("%d\n",ans);
}
int main(){
//  freopen("LG4980.in","r",stdin),freopen("LG4980.out","w",stdout);
    for(int t=read<int>();t--;) Polya();
    return 0;
}

宝石記念貨幣

その質問上記のように。それぞれが過ごすために持っている、17色の合計:しかし、それはより多くの要件となっています。120桁予約。

シンプルと除外だから、および高精度を達成します。

https://cyaron.blog.luogu.org/solution-p2162

私は本当に高精度の高精度であるとみなすことへの書き込み......それを実践していません。

そして、あなたはまた、行列の乗算を使用することができ、および除外したくない:https://www.cnblogs.com/ccz181078/p/7122566.html?utm_source=itdadao&utm_medium=referral

CO int mod=1e9;int n; // qn+r
inter node(int x){
    inter a(15);
    a[0]=x%n,a[1]=x/n;
    return a;
}
inter operator+(CO inter&a,CO inter&b){
    inter ans(15);
    ans[0]=a[0]+b[0];
    if(ans[0]>=n) ++ans[1],ans[0]-=n;
    for(int i=1;i<=14;++i){
        ans[i]+=a[i]+b[i];
        if(ans[i]>=mod){
            if(i+1<=14) ++ans[i+1];
            ans[i]-=mod;
        }
    }
    return ans;
}
inter operator-(CO inter&a,CO inter&b){ // a>=b
    inter ans(15);
    ans[0]=a[0]-b[0];
    if(ans[0]<0) --ans[1],ans[0]+=n;
    for(int i=1;i<=14;++i){
        ans[i]+=a[i]-b[i];
        if(ans[i]<0){
            if(i+1<=14) --ans[i+1];
            ans[i]+=mod;
        }
    }
    return ans;
}
inter operator*(CO inter&a,CO inter&b){
    vector<int128> ans(15);
    ans[0]=(int128)a[0]*b[0]; 
    ans[1]+=ans[0]/n,ans[0]%=n;
    for(int i=1;i<=14;++i){
        ans[i]+=(int128)a[i]*b[0]+(int128)a[0]*b[i];
        for(int j=1;j<=i;++j) ans[i]+=(int128)a[j]*b[i+1-j]*n;
        if(i+1<=14) ans[i+1]+=ans[i]/mod;
        ans[i]%=mod;
    }
    return inter(ans.begin(),ans.end());
}
inter pow(inter a,int b){
    inter ans(15);ans[0]=1;
    for(;b;b>>=1,a=a*a)
        if(b&1) ans=ans*a;
    return ans;
}

int phi(int n){
    int ans=n;
    for(int i=2;i*i<=n;++i)if(n%i==0){
        ans=ans/i*(i-1);
        while(n%i==0) n/=i;
    }
    if(n>1) ans=ans/n*(n-1);
    return ans;
}

int C[20][20];

int main(){
    read(n);
    if(n<17){
        for(int i=1;i<=120;++i) putchar('0');
        puts("");
        return 0;
    }
    for(int i=0;i<=17;++i){
        C[i][0]=C[i][i]=1;
        for(int j=1;j<i;++j) C[i][j]=C[i-1][j-1]+C[i-1][j];
    }
    inter ans(15);
    for(int d=1;d*d<=n;++d)if(n%d==0){
        inter sum(15);
        for(int i=1;i<=17;i+=2) sum=sum+node(C[17][i])*pow(node(i),d);
        for(int i=2;i<=17;i+=2) sum=sum-node(C[17][i])*pow(node(i),d);
        sum=sum*node(phi(n/d));
        ans=ans+sum;
        if(n/d==d) continue;
        sum=node(0);
        for(int i=1;i<=17;i+=2) sum=sum+node(C[17][i])*pow(node(i),n/d);
        for(int i=2;i<=17;i+=2) sum=sum-node(C[17][i])*pow(node(i),n/d);
        sum=sum*node(phi(d));
        ans=ans+sum;
    }
    printf("%03d",ans[14]%1000); // edit 1
    for(int i=13;i>=1;--i) printf("%09d",ans[i]);
    puts("");
    return 0;
}

おすすめ

転載: www.cnblogs.com/autoint/p/10689584.html