170 likes | 323 Views
2011 年西电 ACM 暑期集训. 数论 陆杨柳 (01109043) 20911409@qq.com. 内容. 需要知道的方法 素数 Hash 表 判断素数 Miller_Rabin 算法 因式分解 Pollard- ρ 算法 离散对数 Baby-step Giant-step 算法 中国剩余定理 组合数取模 一些定理. 内容. Hash 表 快速求幂 矩阵快速相乘 素数 欧几里德算法 扩展欧几里德算法 费马小定理. Hash 表. 应用: 宽搜 找字符串 缩短时间. Hash 表.
E N D
2011年西电ACM暑期集训 数论 陆杨柳(01109043) 20911409@qq.com
内容 • 需要知道的方法 • 素数 • Hash表 • 判断素数 Miller_Rabin算法 • 因式分解 Pollard-ρ算法 • 离散对数 Baby-step Giant-step算法 • 中国剩余定理 • 组合数取模 • 一些定理
内容 • Hash表 • 快速求幂 • 矩阵快速相乘 • 素数 • 欧几里德算法 • 扩展欧几里德算法 • 费马小定理
Hash表 应用: 宽搜 找字符串 缩短时间
Hash表 public static int additiveHash(String key, int prime) { int hash, i; for (hash = key.length(), i = 0; i < key.length(); i++) hash += key.charAt(i); return (hash % prime); }
Hash表 /**//** * 改进的32位FNV算法1 * @param data 字符串 * @return int值 */ public static int FNVHash1(String data) { final int p = 16777619; int hash = (int)2166136261L; for(int i=0;i<data.length();i++) hash = (hash ^ data.charAt(i)) * p; hash += hash << 13; hash ^= hash >> 7; hash += hash << 3; hash ^= hash >> 17; hash += hash << 5; return hash; }
快速求幂 在魔法少女世界里的,八神疾风的守护骑士终于收集了足够的魔力,唤醒了夜天之魔导书,不过由于种种原因,夜天之魔导书黑化成了暗之书,对周围城市开始了无差别攻击!为了保护人类,奈叶展开了大范围的防御结界。时空管理局对她们的所在地进行了魔力测定,得到了n个不同的魔力值。其中有一些是奈叶和暗之书的,也可能有一些是其他生物的。现要求奈叶的最低的魔力值大于暗之书的最大值,这样才能保证大家的安全。问这样的可能有多少种?(n<1000000000&&n>1,输出结果模9973取余,共有T组数据,T<=100000)例:n=3时,(设数值为a<b<c)可能情况为:为5种1.奈叶的魔力值:c 暗之书的魔力值:a 2.奈叶的魔力值:c 暗之书的魔力值:b 3.奈叶的魔力值:c 暗之书的魔力值:a b 4.奈叶的魔力值:c b 暗之书的魔力值:a 5.奈叶的魔力值:b 暗之书的魔力值:a (Problem 1096 - 绝对防御) Input 输入T 接下来输入T组数据。每组数据一行,表示有n个不同的魔力测定值。 Output 输出对应于每个n的可能情况有多少种。 Sample Input 523456 Sample Output 151749129 2^(n-1)*(n-2)+1
快速求幂 x^n%k double power(double x, int n,int k) // x^n%k{ double res;res = 1.0; while (n > 0) { if ((n % 2) == 0) { x = x*x; x = x%k; n = n/2; } else { n = n-1; res = x*res; res = res%k; } } return res%k;}
矩阵快速相乘 Problem 1013 - 时间工厂 zyf总是有很多奇异的想法,他最近常常幻想着以后能开这么一个工厂,可以把前三天里生产出来的东西拿到今天来拼在一起作为今天生产的东西。假如前三天生产出来的产品数分别是x,y,z,那么今天就能生产出x+y+z个。这样一来只要前三天的投入,接下来的工厂每一天都是0成本运作,但产品数却在极速增加,相当暴利。 当然,为了防止地球被破坏,为了维护世界的和平,zyf是不会让工厂每天生产出来的东西超过1000000006个的,如果超过了,就不停减去1000000007,减到不超过为止。 现在zyf想知道如果第一、二、三天分别生产a,b,c个产品的话,第n天会生产出多少产品呢? Input 输入数据的第一行case数。 接下来每一行都有四个数字a,b,c,n(1<=a,b,c,n<=10^9),意义如上文. Output 对于每个case输出一行,第n天生产的产品数。 Sample Input 21 2 3 41 1 1 5 Sample Output 65 0 0 1 1 0 1 0 1 1
素数 Problem 1003 - 最喜欢的数字 Description zyf最喜欢的数字是1!所以他经常会使用一些手段,把一些非1的数字变 成1,并为此得意不已。他会且仅会的两种手段是: 1.把某个数m除以某个质数p——当然p必须能整除这个数,即m=m/p 2.把某个数m减1,即m=m-1 有一天他突发奇想,想把[a,b]区间中所有的数一个一个地变成1,这是一个巨大的无聊的工程,所以他想知道他最少得花多少操作才能达到目 的。 Input 输入包含多组数据(1000组数据),EOF结束。 每组数据以两个整数开头:a,b(0<a<=b<=100000),意义如题意描述。 Output 每组数据输出一行,最少操作数。 Sample Input 2 33 511 12 Sample Output 243 Hint
素数 最简单的素数筛选法 prime[]为bool初始值为true for( i=3;i<=sqrt(n);i+=2 ){ if(prime[i]) for( j=i+i; j<=n; j+=i ) prime[j]=false; }优化不是一点。。。。
素数 素数筛选法优化 bool型数组里面只存奇数不存偶数。如定义prime[N],则0表示3,1表示5,2表示7,3表示9...。如果prime[0]为true,则表示3时素数。prime[3]为false意味着9是合数。2*k+3,for循环增量变为2*i+3。。。每一次用当前已得出的素数筛选后面的数的时候可以一步跳到已经被判定不是素数的数后面,这样就减少了大量的重复计算。就是for循环的初始值变了i+(2*i+3)*(i+1) 。。。 个人认为。。。还是打表好。。。
欧几里德算法 求最大公约数 int Gcd(int a, int b) { if(b == 0) return a; return Gcd(b, a % b); }
扩展欧几里德算法 Problem 1101 - 提耶利亚的空间切割 机动战士高达OO是被称为高达系列中机种最混乱,火力最强大,场面最华丽的作品。比如说其中提耶利亚·厄德就是另类的代表。曾被利冯兹~阿尔马克用枪杀死,不过他的意识已和VEDA(量子计算机)相结合,变得更加为完美。在一场关系到人类生死存亡的战役中,在敌我战斗力比为一万比一的情况下,提耶利亚马力全开,进行了一场华丽的战斗。其间提耶利亚利用VEDA进行了大量的计算,其中之一便是宇宙空间中无限延展的量子切割面。在空间中有n个量子平面,其两两相交,每3个平面有且仅有一个公共点,任意4个平面都不共点。需求得这样的n个量子面把空间分割为多少个领域。 (有T组数就T<=200,n>2&&n<=1000000000,输出模9973取余) Input 先输入T,(T组数据)每组数据输入一行,n (n个量子面) Output 输出n个量子面能把空间分割成多少个领域。 Sample Input 534567 Sample Output 815264264 c(3,n+1)+n+1
对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整 数对 x,y ,使得 gcd(a,b)=ax+by。 求解 x,y的方法的理解 设 a>b。1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;2,ab<>0 时 设 ax1+by1=gcd(a,b);bx2+(a mod b)y2=gcd(b,a mod b); 根据朴素的欧几里德原理有 gcd(a,b)=gcd(b,a mod b); 则:ax1+by1=bx2+(a mod b)y2; 即:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2; 根据恒等定理得:x1=y2; y1=x2-(a/b)*y2; 这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2. 上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以 结束。
扩展欧几里德算法 void extend_Eulid(int a,int b) { if(b == 0) { x = 1;y = 0;q = a; } else { extend_Eulid(b,a%b); int temp = x; x = y; y = temp - a/b*y; } }
费马小定理 假如p是质数,且(a,p)=1,那么 a^(p-1) ≡1(mod p) 假如p是质数,且a,p互质,那么 a的(p-1)次方除以p的余数恒等于1