HDU2481 Toy (数论好题)

该题果然是个好题啊!

题意来自上一题, ( http://blog.csdn.net/jayye1994/article/details/37814965 )  BZOJ
1002: [FJOI2007]轮状病毒

上一题是旋转后相同视为不同情况,这题旋转后相同视为同一种情况。就这么一个小小的区别,

上一题用到了dp,这一题用到了dp、筛素数、二进制模拟乘法、矩阵、快速幂、欧拉函数、burnside引理。。

同样是人(题)。。做人(题)的差距怎么就这么大呢。。

数据范围:周围是n个点,答案取模m, n<=10^9, m <= 10^9

思路:

要做这题首先是肯定要会burnside引理的,不会的可以去做几题,刘汝佳的训练指南上有。

然后考虑有n种置换,分别是不动、旋转i个单位(i < n)。

首先解决不动的情况,实际上就是轮状病毒要求的结果,可是这里的n<=10^9,那题我计算的复杂度是O(n^2)的,

计算公式也不能快速幂,然后那题的dp公式可以推出dp[i][1] = 3*dp[i-1][1] - dp[i-2][1],推结果ans的话我就推晕了,

那么打个表就可以发现规律。。ans[i] = 3*ans[i-1] - ans[i-2] + 2,于是不动的情况解决了。。。

接下来就是要求旋转的情况了,旋转i个单位,很容易可以得知循环节是n / gcd(n, i) ,循环的个数为gcd(i, n),所以每gcd(i,n)构成一块,每一块都是完全相同的,如下图所示

想了下还是把上一题的dp贴过来,这样子看起来比较清楚。

题目就是求最小生成树的种数,中心的点必须要和周围的一圈点连通,可以先不要管环,先考虑链的情况

dp[ i ][ 0 ]表示第i个点还没和中心点连通,并且前i-1个点和中心点或者第i个点是连通的

dp[ i ][ 1 ]表示前i个点全部都已经和中心点连通了

很容易可以推出状态转移方程 :

dp[ i ][ 0 ] = dp[ i-1 ][ 0 ] + dp[ i-1 ][ 1 ]

dp[ i ][ 1 ] = dp[ i-1 ][ 0 ] + dp[ i-1 ][ 1 ]*2

那么对于n轮状病毒,可以枚举第一个点和多少个周围的点连通,其余的点就是一条链的情况了。

比如说i=2,n=6,那么gcd(2,6) = 2,循环长度是2,也就是说红色线段和绿色线段在重复出现,那么可以知道中间的所有的点都要是连通的,如果两侧的点也都和中心点连通了的话,绿色线段就要删掉,情况数就是dp[ gcd(i,n) ][ 1 ]。求循环长度是d的个数可以用欧拉函数来求,所以不需要枚举i(i<=n),只需要枚举n的因子就可以了。

如果某一侧点没有和中心点连通的话,绿色线段是必要的,情况数就是2*dp[ gcd(i,n) ][0],因为有两侧所以乘2,但是要注意如果这一段所有的点都没和中心点连通的话是不行了,所以情况数还需要减去 2 * 1。

然后问题差不多已经解决了,不过还有一个问题,最后算出的答案还需要除以n,但是n和m不一定互质,所以不能求逆元

所以是求(a/b) mod c,因为知道a/b是一个整数,所以ans = a/b + xc,然后ans * b = a + xbc = a mod (bc),所以可以求出a mod (bc)然后除以b就可以了,中间乘法会爆long long,所以要二进制位上加法来模拟乘法。

code:

HDU2481 Toy (数论好题)

时间: 2024-11-11 08:06:28

HDU2481 Toy (数论好题)的相关文章

数论 --- 简单题

吃糖果 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 22376    Accepted Submission(s): 6396 Problem Description HOHO, 终于从Speakless手上赢走了所有的糖果,是Gardon吃糖果时有个特殊的癖好,就是不喜欢将一样的糖果放在一起吃,喜欢先吃一种,下一次吃另一 种,这样:

BZOJ1968: [Ahoi2005]COMMON 约数研究(数论 水题)

Description Input 只有一行一个整数 N(0 < N < 1000000). Output 只有一行输出,为整数M,即f(1)到f(N)的累加和. Sample Input 3 Sample Output 5 Solve: 数论水题,求因数又不是质因数,所以,只要求出对于[1 , n]有多少个倍数,就表示[1 , n]中以i为因数的是哪些,加起来就可以了 Code: 1 #include <bits/stdc++.h> 2 using namespace std;

POJ 3358 Period of an Infinite Binary Expansion( 数论好题 + 欧拉定理 + 欧拉函数 )

POJ 3358 Period of an Infinite Binary Expansion( 数论好题 + 欧拉定理 + 欧拉函数 ) #include <cstdio> #include <cstring> #include <algorithm> #include <algorithm> using namespace std; typedef long long LL; LL fac[ 100000 ], pf; LL gcd( LL a, LL

数论十题

数论十题 Problem Zero:[neerc2011]Gcd guessing game 现在有一个数x,1 ≤ x≤ n,告诉你n,每次你可以猜一个数y,如果x==y则结束,否则返回gcd(x,y),问最少只要几次就可以保证猜出答案. 本题纯属娱乐.仅仅是一个GCD的游戏,跑题了. 因为本题要求最坏情况,我们直观地猜想就是每次返回都是1.由于答案有可能是质数,而判定一个数,必须要把含有这个质因子的数问一遍.于是,我们引出这样一个思路,将所有1-n的质数分组,每组的积<=n,答案就是组数.

uva 10006 数论入门题

这是一个入门的数论题目 , 只需要简单的找素数和快速幂取模 题意:输入一个数 n , 如果这个数是非素数 , 问是不是 这个2~n-1区间的所有数都满足 ? 解法:由于数据量不大 , 可以直接暴力求解 解法1: 暴力求解 #include <iostream> #include <string.h> #include <stdio.h> using namespace std; long long prime[65010]; long long n; void init

HDU 2674 N!Again (数论-水题)

N!Again Problem Description WhereIsHeroFrom:             Zty, what are you doing ? Zty:                                     I want to calculate N!...... WhereIsHeroFrom:             So easy! How big N is ? Zty:                                    1 <=

HDU 4143 A Simple Problem(数论-水题)

A Simple Problem Problem Description For a given positive integer n, please find the smallest positive integer x that we can find an integer y such that y^2 = n +x^2. Input The first line is an integer T, which is the the number of cases. Then T line

数论简单题 组合数

本人水平有限,题解不到为处,请多多谅解 本蒟蒻谢谢大家观看 题目: 数论简单题 (simple.cpp/in/out 1s 256M) 由于最终结果可能超过int的范围,因此请将运算结果对1000000007取模. Input 第1行,一个整数T(T <= 200000),表示数据组数. 第2行至第T+1行,每行两个整数m, n. 0 < m <= n <= 2000 Output 共T行,每行输出一个整数,代表求和结果. Sample Input 3 1 1 2 3 3 3 Sa

HDU2481 Toy

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 661    Accepted Submission(s): 363 Problem Description On birthday, Anthony got a toy. It is constructed with N+1(N>=3) balls and 2*N sticks. All