• 【POJ】2154 Color


    题意:n个珠子的环,之多着n种颜色,考虑旋转,不考虑翻转。问模P的方案数。

    运用Burnside定理,有n个置换,每个置换使得着色不变的着色个数有GCD(n,i)个。

    GCD(n,i)个的原因:【POJ】2409 Let it Bead

    由于n达到十亿,显然不能枚举。但是可以发现,GCD(n,i)即n约数的个数很少。

    问题转化为1~n有多少个数,使得GCD(n,i)=k。其中k是n的约数。这个问题等价于与n/k互质的个数有多少,那么容斥就能搞定。

    由于有模P,Burnside定理最后要除以n,但是n与P不一定互质,可能没有逆元。观察到分子,不妨先都除以n,就避免了这个问题。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<vector>
      5 #define EPS 1e-8
      6 #define MAXN 32000
      7 using namespace std;
      8 vector<int> fac;
      9 vector<int> g;
     10 vector<int> prime;
     11 int P;
     12 bool p[MAXN];
     13 void Init() {
     14     int i, j;
     15     memset(p, true, sizeof(p));
     16     for (i = 2; i < 180; i++) {
     17         if (p[i]) {
     18             for (j = i * i; j < MAXN; j += i)
     19                 p[j] = false;
     20         }
     21     }
     22     prime.clear();
     23     for (i = 2; i < MAXN; i++) {
     24         if (p[i])
     25             prime.push_back(i);
     26     }
     27 }
     28 void Factor(int n) {
     29     int i, tmp;
     30     fac.clear();
     31     tmp = (int) (sqrt((double) n) + EPS);
     32     for (i = 1; i <= tmp; i++) {
     33         if (n % i == 0) {
     34             fac.push_back(i);
     35             if (i == tmp && i * i == n)
     36                 continue;
     37             fac.push_back(n / i);
     38         }
     39     }
     40 }
     41 int PowMod(int a, int b, int c) {
     42     int res;
     43     a %= c;
     44     for (res = 1; b; b >>= 1) {
     45         if (b & 1) {
     46             res *= a;
     47             res %= c;
     48         }
     49         a *= a;
     50         a %= c;
     51     }
     52     return res;
     53 }
     54 void Prime(int x) {
     55     int i, tmp;
     56     g.clear();
     57     tmp = (int) (sqrt((double) x) + EPS);
     58     for (i = 0; prime[i] <= tmp; i++) {
     59         if (x % prime[i] == 0) {
     60             g.push_back(prime[i]);
     61             while (x % prime[i] == 0)
     62                 x /= prime[i];
     63         }
     64     }
     65     if (x > 1)
     66         g.push_back(x);
     67 }
     68 int Mul(int x, int &k) {
     69     int i, ans = 1;
     70     for (i = k = 0; x; x >>= 1, i++) {
     71         if (x & 1) {
     72             ans *= g[i];
     73             k++;
     74         }
     75     }
     76     return ans;
     77 }
     78 int Count(int x) {
     79     int i, j, t, tmp, ans;
     80     Prime(x);
     81     ans = 0;
     82     t = (int) g.size();
     83     for (i = 1; i < (1 << t); i++) {
     84         tmp = Mul(i, j);
     85         if (j & 1)
     86             ans += x / tmp;
     87         else
     88             ans -= x / tmp;
     89     }
     90     return (x - ans) % P;
     91 }
     92 int main() {
     93     int c;
     94     int n, ans, i;
     95     Init();
     96     scanf("%d", &c);
     97     while (c--) {
     98         scanf("%d%d", &n, &P);
     99         Factor(n);
    100         ans = 0;
    101         for (i = 0; i < (int) fac.size(); i++) {
    102             ans += PowMod(n, fac[i] - 1, P) * Count(n / fac[i]);
    103             ans %= P;
    104         }
    105         printf("%d\n", ans);
    106     }
    107     return 0;
    108 }
  • 相关阅读:
    支付宝支付私钥和公钥创建
    (五)Maven中的聚合和继承
    Windows 下Nexus搭建Maven私服
    (四)Maven中的仓库
    zookeeper安装和使用 windows环境
    (一)Redis之简介和windows下安装radis
    (错误) Eclipse使用Maven创建Web时错误
    (三)引用中央仓库中不存在的jar包
    (二)依赖传递
    (一)Maven基础及第一个Maven工程
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2678819.html
Copyright © 2020-2023  润新知