zoukankan      html  css  js  c++  java
  • 【poj2154】 Color

    http://poj.org/problem?id=2154 (题目链接)

    题意

      n个珠子的项链,可以染上n中颜色,项链可以旋转不能翻转,求染色方案数。

    Solution

      经典的公式:

    egin{aligned} ans &= sum_{i=0}^{n-1} gcd(n,i)\ &= sum_{d|n} (n^{d-1}*φ(frac{n}{d})) end{aligned}

      于是就可以求了,然而时限卡太死,只能用int,还必须枚举质数求phi。。

    代码

    // poj2154
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define inf 1<<30
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    
    bool vis[1000010];
    int p[100010],P;
    
    int phi(int x) {
    	int t=x;
    	for (int i=1;p[i]<=sqrt(x);i++) if (x%p[i]==0) {
    			t=t-t/p[i];
    			while (x%p[i]==0) x/=p[i];
    		}
    	if (x>1) t=t-t/x;
    	return t%P;
    }
    int power(int a,int b) {
    	int res=1;
    	while (b) {
    		if (b&1) res=res*a%P;
    		b>>=1;a=a*a%P;
    	}
    	return res;
    }
    int main() {
    	for (int i=2;i<=1000000;i++) {
    		if (!vis[i]) p[++p[0]]=i;
    		for (int j=1;j<=p[0] && p[j]*i<=1000000;j++) {
    			vis[p[j]*i]=1;
    			if (i%p[j]==0) break;
    		}
    	}
    	int n,ans;
    	int T;scanf("%d",&T);
    	while (T--) {
    		scanf("%d%d",&n,&P);ans=0;
    		for (int i=1;i*i<=n;i++) if (n%i==0) {
    				ans+=power(n%P,i-1)*phi(n/i);
    				if (i*i!=n) ans+=power(n%P,n/i-1)*phi(i);
    				ans%=P;
    			}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    1442. Count Triplets That Can Form Two Arrays of Equal XOR
    1441. Build an Array With Stack Operations
    312. Burst Balloons
    367. Valid Perfect Square
    307. Range Sum Query
    1232. Check If It Is a Straight Line
    993. Cousins in Binary Tree
    1436. Destination City
    476. Number Complement
    383. Ransom Note
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6257673.html
Copyright © 2011-2022 走看看