被虐的两道数论题

我说……我这么闲,那么……写篇日志吧,谨以此纪念我无限趋向于0的智商,那天……犯了个傻的两道题……顺便orz一下HGR以及HYY神犇……
       
Problem A:
        给定n,k,求任意一个序列a,使得∏(1≤i≤k)(1+1/ai)=1+(2^k-1)/n。(1≤n≤2^31,1≤k≤31)

本来这题目是很水的……但是……我当即立断,机智地化了简:(Σ(b∈[1,k])ab1ab2ab3…abp)/∏(1≤i≤k)ai=(2^k+n-1)/n。随后我发现,ai与ai+1约分后必须取遍n的质因数(好吧,预处理先把右边约分),然后我开始对n进行分解,然后各种枚举……由于我的程序比较挫,它一度陷入死循环……努力了一个多小时后……我发现它……比暴力还慢,于是我有改呀改,改到没时间写第三题水水的trie。我暴搜出所有情况,然后各种剪枝……搞到最后只拿到30分的暴力分,深深的维和感。
     
 
后来看到了题解,发现我傻了,题解把(2^k+n-1)/n进行了简单的分解:当2丨n时,(2^k+n-1)/n=((2^(k-1)+n/2-1)/(n/2))*(1+1/(2^k+n-2)),否则(2^k+n-1)/n=((2^(k-1)+(n+1)/2-1)/((n+1)/2))*(1+1/n),然后一阵递归,边界嘛,显然k=1时,a={n}看到题解后不到5分钟就A了这题目T_T。
     
  如此水的代码,我就不发了……
        Problem B:
       
给定n,m(1≤n,m≤10^16),问长度为m的只由1~n间数字构成的圆周序列的个数。

一开始看,嗯,圆排列,就这么简单?然后发现我跪了,根本不一样嘛,于是我使劲想,却也只弄出来60分做法(必须承认,这是暴力分),然后,HGR大神给了一番讲解,但是整个教室似乎没人听懂(HYY大神大概是懂了……)。HGR大神大概是算计好的,在恰当的时刻来巡视我们,然后机智接受了全教室唯一一个妹纸的再讲解邀请,然后给了她各种福利(就是厚厚的一本书,看内容大概是排列组合一类的,哼,我有人品神器《初等数论》),但是似乎还是没人懂(他们都不知道欧拉函数,当然听不懂)。当晚,我把《初等数论》放在床头,于是我失眠了,然后想出了这题目自己的证明,比HGR的好懂多了(那是因为我只是个苣蒻),原来的定理是这样的:记序列个数为f(n,m),那么我们有f(n,m)=(1/m)*(Σ(1≤l≤m)n^(gcd(l,m)))=(1/m)*(Σ(d丨m)(n^d)*φ(m/d))。然后我给出一个“生动形象”的证明:
     
 
首先,我们有m*f(n,m)=Σ(a0a1a2...am-1∈[1,n])Σ(0≤l<m)[a0a1a2...am-1=alal+1...am-1a0...al-1],这里的中括号表示当括号内表达式为true时取1,否则取0。传说中HGR大神就是这个东西一直给妹纸讲不清,我也不知道我能不能说清。我们可以想象一下a0a1a2...am-1∈[1,n]作为全集的一个集合,显然f(n,m)取了集合中的一部分,而假如我们对f(n,m)中每个圆周序列进行旋转,就会产生m*f(n,m)个序列。比如序列AB可以扩展成AB和BA,但是BA是不存在于f(n,m)中的(在已有AB的情况下),那么全部旋转后就能取遍f(n,m)的补集。然而对于序列AA,旋转后产生两个AA,此时出现重复,即在取遍全集的基础上部分元素被多次取到。很容易发现当l=0时,a0a1a2...am-1=alal+1...am-1a0...al-1显然成立,此时就取遍了全集,而当l≠0时,等式一旦成立,取到的点一定是已经被重复覆盖(比如序列AA),然后……式子就证明完了,真是“生动形象”的证明。
     
 
接下来我们考虑将式子化简,首先,交换两个Σ是不会破坏结果的,那么式子变成Σ(0≤l<m)Σ(a0a1a2...am-1∈[1,n])[a0a1a2...am-1=alal+1...am-1a0...al-1],于是乎,我们可以对单个点进行讨论啦。接下来的证明,HGR大神用了各种同余,以及拓展欧几里得定理(所以大家都听不懂),作为一个苣蒻,我就不写了,我同样有“生动形象”的证明:
 
      为了帮助大家理解,我们可以先考虑
l丨m的情况,此时,我们可以把长度为m的序列分块,每块长度为l,由a0a1a2...am-1=alal+1...am-1a0...al-1显然可以分解成当i≡j(mod
l)时,ai=aj,那假如我们确定了ai(0≤i<l),我们就能确定ai+kl(1≤k<m/l),于是乎,只要我们确定了a0...al-1,我们就能确定整个序列,所以序列的可能性,只有n^l
种,于是m*f(n,m)=Σ(1≤l≤m)n^(gcd(l,m)),就成立了。但是如果l不整除m,我们记d=gcd(l,m),此时同样可以对序列进行分块,每块长度为d,由于当i≡j(mod l)时,ai=aj,只要确定了ai(0≤i<l),我们就能确定a(i+kl)mod
m
(1≤k<m/d),显然,i+kd有可能超出m的边界(所以我写了mod
m),此时由于一共有m/d个块,而m/d又与l互质,我们可以对原图进行压缩,看成m/d的d个剩余系,因为(l,m/d)=1,由于什么剩余系定理(不知道应该叫什么),i+kd是可以取遍整个剩余系的,于是,只要确定了ai(0≤i<d),i在其他块的映射位置也都能确定,所以合法的序列只有n^d种。该做法能拿90分。
         继续化简,很容易可以得到m*f(n,m)=Σ(d丨m)(n^d)*φ(m/d),证明的话我就不废话了(显然……)。再显然,我们可以用神奇的Pollard-rho算法,在四次根号m的复杂度下对m进行质因数分解,利用φ(n)的积性,在计算所有d的同时顺手把φ(m/d)给算出来,然后……就可以A啦……
     
  代码……?你想多了……
        停电导致本文进度一度停滞(渣手机写不了日志),谨以此纪念我完跪的二中培训……

时间: 2024-10-17 15:28:50

被虐的两道数论题的相关文章

有趣的两道数论题——2017华杯初赛小高组

首发于订阅号 嗨编程,这是一个以嗨为目标的编程订阅号(仅仅是目标而已),扫码可关注,争取每周5更. 5.从1-20这20个整数中任意取11个数,其中必有两个数的和等于() A. 19    B.20    C.21    D.22 答案:C 解析: 最小的11个数是1~11,当中最大的两个数之和是21,最大的11个数是10~20,当中最小的两个数之和是21,即可确定答案. 9.在一个自然数的所有因数中,能被3整除的因数比奇因数多5个,那么这个自然数最小是_____ 答案:72 解析:考虑对这个自

数论题总结

这几天做了几道微不足道的数论题,感觉做法都十分的高啊,我这种僵化的思想是很难有那样的切题知识水平的.然后做了几道题,感觉也有点熟悉数学的那一套理论了,虽然我还是太弱,但是有点东西还是要讲出来的嘛,一起谈笑风生,积累人生经验.闷声发大财虽然好,但是是不支持的. 上面那句话看不懂就无视吧. 那么对于数论题,我们应该如何下手呢??我总结了一些分析技巧和优化技巧,希望有用(希望考场推得出来). 题目分析: 1.题目给的很直接了,让你求这个那个. 以两道同年的NOI题目为例. 1.荒岛野人 Savage

两道有意思的题目

碰到两道有意思的题目,记录一下. 题目一: 问,对于任意一个正整数,是否存在一个它的倍数全是由1和0组成? 例如: 1 * 1 = 1 2 * 5 = 10  (2的5倍是10,10由1和0组成) 3 * 37 = 111 (3 的 37 倍是111,111 全部由1组成) 4 * 25 = 100 (4 的 25 倍是100,100 由1和0组成) 5 * 20 = 100 (5 的 20 倍是100,100由1 和 0 组成) …… 现在需要判断,随便给一个正整数,是否存在一个它的倍数满足题

[sdut]2623+[sdut]2878//四五届省赛中的两道数学期望

两道数学期望的题今天一起总结上来. 1.the number of steps(第四届省赛) 1 #include <iostream> 2 #include <string.h> 3 #include <iomanip> 4 using namespace std; 5 double dp[100][100]; 6 int n; 7 double a,b,c,d,e; 8 9 int main() 10 { 11 while(cin>>n&&

bzoj3209:3209: 花神的数论题

觉得还是数位dp的那种解题形式但是没有认真的想,一下子就看题解.其实还是设置状态转移.一定要多思考啊f[i][j]=f[i-1][j]+g[i-1][j] g[i][j]=f[i-1][j-1]+g[i-1][j]; 然后我就开始gang.然后先是for for j没有从0开始.然后是cnt增加的时候忘了*,接着是1<<tmp没有用ll,还有是读入优化没有用longlong,最后成功的过了若干较小的数据.WAWAWAWAWA5发.最后发现指数不能直接取模!.终于AC了喜极而泣TAT =>

分享两道笔试题目

前几天,给成都的某家公司投了个简历,给发了两道笔试题目,与大家分享一下.附上自己的解题过程,写得不好的地方,还请博友多多指教. 一 .  设计程序输出销售及收费清单 一个电商平台对在其平台之上销售的除了书籍.食品以及药物以外的商品收取 10% 的费用.而对于进口的商品则额外收取 5% 的附加费用.对于平台抽取的费用计算时,舍入的规则是:对于 n% 抽取率,价格为 p的商品, np/100 的值就近舍入到 0.05(如: 7.125 -> 7.15, 6.66 -> 6.70 ). 卖家卖出一些

两道拓扑排序的问题

多久没写东西了啊.... 两道拓扑排序Liv.1的题....方法是一样的~~ <拓扑排序·二> 题目:http://hihocoder.com/contest/hiho81/problem/1 一个电脑网路,单向边,如果存在边u->v,那么u的病毒会感染到v. 要点,不存在环!那么如果u的入度=0的话,那么u中的病毒数不会再变化. 想到拓扑排序.不断删去入度为0的点.每次删去节点u,如果存在u->v,那么病毒数 num[v] += num[u].问题解决. (用queue实现拓扑排

病毒的侵扰和再侵扰两道AC自动机的应用

HDU2896 病毒的侵扰 http://vjudge.net/problem/viewProblem.action?id=16404 题目大意: 记录每个病毒的编号,并给出一些网站的源码,分别输出网站及其对应编号中所含病毒的编号,没有就不输出 最后输出有病毒网站的个数 这道题需要注意的是这个所有ASCII码均会用到,所以我之前傻傻地写str[i]-'a'还不知为什么会错简直苦逼~~ 这里直接用ch[now][str[i]]找到对应位置即可 因为要记录编号,为了防止重复访问,我对query中进行

数论题常用式子

最近在做数论题,积累一些式子. \([x=1]=\sum_{d|x}\mu(d)\)(莫比乌斯函数定义) 然后才推出莫比乌斯函数的公式以及莫比乌斯函数是积性函数. \(\sum_{i=1}^n[\gcd(i,n)=1]=\varphi(n)\)(欧拉函数定义) 根据一些计数原理,能推出来欧拉函数的公式,从而推出欧拉函数是积性函数. \(\sum_{i=1}^ni[\gcd(i,n)=1]=\frac n 2\varphi(n)\)(当n=1时为1) 或者写为\(\sum_{i=1}^ni[\gc