zoukankan      html  css  js  c++  java
  • 【HDU】3441 Rotation

    题意:给出A和C(1<=A,C<=10^9),所有满足B * B * K + 1 = A * A, (K >= 0)的B,构成边长为B的正方形,等角度的围绕在一个小正方形的周围。用C种颜色着色,边长为B的正方形旋转后相同视为相同的方案,整个图形绕中间的小正方形旋转后相同也视为相同的着色方案,求着色方案数。

    整体思路是:

    首先,忽略中间的小正方形,得到所有的B,求边长为B的着色的方案数X。

    其次,将每个B看成一个点,求用X种颜色对一个环着色的方案数。

    最后,将答案乘以C。

    要得到所有的B。由于A*A达10^18次方,根号n的复杂度寻找B肯定行不通。观察到B*B*K=A*A-1=(A+1)*(A-1)。

    因此,分别对A+1和A-1分解质因子。

    通过DFS枚举质因子得到B的值,同时剩下的质因子是K的。

    再通过一个DFS对剩下的质因子枚举出K的约数即可。

    对正方形着色:【HDU】1812 Count the Tetris

    对环着色:【POJ】2154 Color

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define MAXN 32000
      5 #define P 1000000007
      6 typedef long long LL;
      7 using namespace std;
      8 bool p[MAXN], flag1, flag2;
      9 LL A, B, C, K;
     10 LL ans1, ans2;
     11 int depth1, depth2;
     12 int prime[MAXN], factor[MAXN];
     13 int prime_size, factor_size, prifac_size;
     14 struct node {
     15     int val, cnt;
     16 } prifac[MAXN];
     17 void Init() {
     18     int i, j;
     19     memset(p, true, sizeof(p));
     20     for (i = 2; i < 180; i++) {
     21         if (p[i]) {
     22             for (j = i * i; j < MAXN; j += i)
     23                 p[j] = false;
     24         }
     25     }
     26     prime_size = 0;
     27     for (i = 2; i < MAXN; i++) {
     28         if (p[i])
     29             prime[prime_size++] = i;
     30     }
     31 }
     32 void Factor(int x) {
     33     int i;
     34     for (i = 0; prime[i] * prime[i] <= x; i++) {
     35         while (x % prime[i] == 0) {
     36             factor[factor_size++] = prime[i];
     37             x /= prime[i];
     38         }
     39     }
     40     if (x > 1)
     41         factor[factor_size++] = x;
     42 }
     43 LL Pow(LL a, LL b) {
     44     LL ans;
     45     for (ans = 1; b; b >>= 1) {
     46         if (b & 1)
     47             ans *= a;
     48         a *= a;
     49     }
     50     return ans;
     51 }
     52 LL PowMod(LL a, LL b, LL c) {
     53     LL ans;
     54     a %= c;
     55     for (ans = 1; b; b >>= 1) {
     56         if (b & 1) {
     57             ans *= a;
     58             ans %= c;
     59         }
     60         a *= a;
     61         a %= c;
     62     }
     63     return ans;
     64 }
     65 LL ExtGcd(LL a, LL b, LL &x, LL &y) {
     66     LL t, d;
     67     if (b == 0) {
     68         x = 1;
     69         y = 0;
     70         return a;
     71     }
     72     d = ExtGcd(b, a % b, x, y);
     73     t = x;
     74     x = y;
     75     y = t - a / b * y;
     76     return d;
     77 }
     78 LL InvMod(LL a, LL n) {
     79     LL x, y;
     80     ExtGcd(a, n, x, y);
     81     return (x % n + n) % n;
     82 }
     83 LL Count1(LL n) {
     84     LL ans;
     85     if (n & 1)
     86         ans = (n - 1) * (n / 2 + 1) / 2 + 1;
     87     else
     88         ans = (n / 2) * (n / 2);
     89     return ans;
     90 }
     91 LL Count2(LL n) {
     92     LL ans;
     93     if (n & 1)
     94         ans = (n + 1) * (n - 1) / 2 + 1;
     95     else
     96         ans = n * n / 2;
     97     return ans;
     98 }
     99 LL Square(LL x, LL k) {
    100     LL ans;
    101     ans = PowMod(k, x * x, P);
    102     ans += PowMod(k, Count1(x), P) * 2 % P;
    103     if (ans >= P)
    104         ans -= P;
    105     ans += PowMod(k, Count2(x), P);
    106     if (ans >= P)
    107         ans -= P;
    108     return ans * InvMod(4, P) % P;
    109 }
    110 LL Phi(LL x) {
    111     int i;
    112     LL res;
    113     res = x;
    114     for (i = 0; i < prifac_size; i++) {
    115         if (prifac[i].cnt && x % prifac[i].val == 0)
    116             res -= res / prifac[i].val;
    117     }
    118     return res % P;
    119 }
    120 void Find(int now, int index, LL res, LL color) {
    121     if (now == depth2) {
    122         flag2 = true;
    123         ans2 += PowMod(color, res, P) * Phi(K / res) % P;
    124         if (ans2 >= P)
    125             ans2 -= P;
    126     } else {
    127         int i, j;
    128         for (i = index; i < prifac_size; i++) {
    129             for (j = 1; j <= prifac[i].cnt; j++)
    130                 Find(now + 1, i + 1,
    131                         res * Pow(prifac[i].val, j),
    132                         color);
    133         }
    134     }
    135 }
    136 LL Burnside(LL n, LL k) {
    137     ans2 = 0;
    138     for (depth2 = 0;; depth2++) {
    139         flag2 = false;
    140         Find(0, 0, 1, k);
    141         if (!flag2)
    142             break;
    143     }
    144     return ans2 * InvMod(n, P) % P;
    145 }
    146 void DFS(int now, int index, LL res) {
    147     if (now == depth1) {
    148         flag1 = true;
    149         B = res;
    150         K = (A - 1) * (A + 1) / (B * B);
    151         ans1 += Burnside(K, Square(B, C));
    152         if (ans1 >= P)
    153             ans1 -= P;
    154     } else {
    155         LL tmp;
    156         int i, j;
    157         for (i = index; i < prifac_size; i++) {
    158             for (j = 2; j <= prifac[i].cnt; j += 2) {
    159                 prifac[i].cnt -= j;
    160                 tmp = res * Pow(prifac[i].val, j >> 1);
    161                 DFS(now + 1, i + 1, tmp);
    162                 prifac[i].cnt += j;
    163             }
    164         }
    165     }
    166 }
    167 LL Cal() {
    168     int i, j;
    169     factor_size = prifac_size = 0;
    170     Factor(A - 1);
    171     Factor(A + 1);
    172     sort(factor, factor + factor_size);
    173     for (i = 0; i < factor_size; i = j) {
    174         prifac[prifac_size].val = factor[i];
    175         prifac[prifac_size].cnt = 0;
    176         for (j = i; j < factor_size && factor[i] == factor[j]; j++)
    177             prifac[prifac_size].cnt++;
    178         prifac_size++;
    179     }
    180     ans1 = 0;
    181     for (depth1 = 0;; depth1++) {
    182         flag1 = false;
    183         DFS(0, 0, 1);
    184         if (!flag1)
    185             break;
    186     }
    187     return ans1 * C % P;
    188 }
    189 int main() {
    190     int c, ca = 1;
    191     LL ans;
    192     Init();
    193     scanf("%d", &c);
    194     while (c--) {
    195         scanf("%lld%lld", &A, &C);
    196         if (A == 1)
    197             ans = C;
    198         else
    199             ans = Cal();
    200         printf("Case %d: %lld\n", ca++, ans);
    201     }
    202     return 0;
    203 }
    新博客:www.zhixiangli.com
  • 相关阅读:
    Linux更新时,出现无法更新锁
    Linux显示su:认证失败
    08 redis的缓存预热,雪崩,击穿,穿透问题以及常用的监控参数
    06 redis的哨兵系统的工作流程
    05 redis的主从复制机制的工作流程以及相关基础知识
    03 redis的事务以及锁、过期数据的删除策略、逐出算法、配置文件的核心配置参数
    02 jedis以及redis的持久化
    01 redis的5种基本数据类型的介绍,使用以及应用场景
    M1 MySQL事务知识点的总结
    02 Java文件读写通道的使用以及文件的基本操作方法
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2686931.html
Copyright © 2011-2022 走看看