首先洛谷的题面十分的劝退(至少对我这个菜鸡来说是这样),我来解释一下(原来的英文题面):

有一个有若干个密码(每个密码都可以开箱子)的密码箱,密码是在$0$到$n-1$的数中的,且所有的密码都满足一个条件:如果$x$是密码,$y$也是密码($x$可能等于$y$),那么$(x+y)\%n$也是密码。现在有一个人在试密码,他试了$k$个数,前$k-1$个都是错的,第$k$个是对的。现在你要求这个密码箱最多有多少不同的密码。

显然如果$x$是一个密码,那么$ax(a∈N\&\&ax<n)$也都是密码。根据裴蜀定理,我们先让$num_k$和$n$取一个gcd得到$g$,然后把$g$分解因数得到$fac$个因数。从小到大枚举因数$f$,如果对于一个因数$f$前$k-1$个数都不能整除它,说明它符合题意,这个时候答案就是$\frac{n}{f}$,也就是取它的所有倍数。

然后我们发现这个玩意直接枚举来做的话理论上最差是$O(sqrt(n)k)$的,看起来根本过不去(实际上可以水过去),于是学习了一种筛法的解法。

我们换一种方法检查每个因数是否合法:首先标记$i=1->k-1$中所有的$gcd(num_i,num_k)$为不可取。接下来要用到一个性质:如果一个数$x$不可取,那么$x$所有的因数也一定都不可取(不要搞反了)。这样我们从大到小枚举一下$num_k$的所有因数$fac_i$,每次从小到大枚举$num_k$的质因数$pfac_j$,每次查看$num'=fac_i*pfac_j$(如果这个数存在的话),如果它不可取就将当前的因数标记为不可取,最后正着扫一遍就行了。复杂度$O(fac$ $log(n)log(fac))$(根本跑不满)

Update:讲了以后收到了很多疑问,筛答案那块没啥问题,主要是证明“显然如果$x$是一个密码,那么$ax(a∈N\&\&ax<n)$也都是密码” 这里(根本不显然=。=)和“根据裴蜀定理,我们先让$num_k$和$n$取一个gcd” 这里(为什么取gcd=。=?)。发现自己根本讲不清楚(完全暴露了数学鶸的本质233),看来还是要提高一个知识水平orz

现在更新一下详细证明:

1.为什么“如果$x$是一个密码,那么$ax(a∈N\&\&ax<n)$也都是密码”

这个问题有一个更“朴实”的问法:凭什么你可以用一个$x$和它的所有倍数表示出答案,而不是两个数组合呢?

(讲的时候极尬,完全不会讲TAT)

我们首先证明一个东西:如果$x$是密码,$y$是密码,那么$gcd(x,y)$也是密码

这个东西可以由裴蜀定理得出,问题是裴蜀定理说的是整数,我们要求必须是正整数

不过没关系,因为我们在模$n$剩余系下做,所以我们想$-ax$就等价于$+(kn-a)x(a,k∈N*)$

证明了这个,那么所有“两个数的组合”就都可以表示成它们的$gcd$了,于是问题解决

2.为什么“先让$num_k$和$n$取一个gcd”

暴力做应该不用取,但是筛的时候必须取

首先裴蜀定理告诉我们这样做了之后还是对的

那么为什么必须这样做呢?因为$num_k$中可能还有一个(相对于前$k-1$个数)独特的因数,然后你在排除的时候这个因数根本排不掉,你就把它当成答案了。。。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. const int N=;
  6. long long p[N],fac[N],pfac[N];
  7. long long n,k,g,tot,cnt;
  8. bool una[N];
  9. long long gcd(long long a,long long b)
  10. {
  11. return b?gcd(b,a%b):a;
  12. }
  13. void getf(long long maxx)
  14. {
  15. for(long long i=;i*i<=maxx;i++)
  16. if(maxx%i==)
  17. {
  18. fac[++tot]=i;
  19. if(i*i!=maxx)
  20. fac[++tot]=maxx/i;
  21. }
  22. }
  23. void getpf(long long maxx)
  24. {
  25. for(long long i=;i*i<=maxx;i++)
  26. if(maxx%i==)
  27. {
  28. pfac[++cnt]=i;
  29. while(maxx%i==) maxx/=i;
  30. }
  31. if(maxx!=) pfac[++cnt]=maxx;
  32. }
  33. int main()
  34. {
  35. scanf("%lld%lld",&n,&k);
  36. for(int i=;i<=k;i++)
  37. scanf("%lld",&p[i]);
  38. if(!p[k]&&k==) printf("%lld",n),exit();
  39. p[k]=gcd(p[k],n),getf(p[k]),getpf(p[k]);
  40. sort(fac+,fac++tot);
  41. for(int i=;i<k;i++)
  42. una[lower_bound(fac+,fac++tot,gcd(p[i],p[k]))-fac]=true;
  43. for(int i=tot;i;i--)
  44. if(!una[i])
  45. for(int j=;j<=cnt&&fac[i]*pfac[j]<=n;j++)
  46. {
  47. long long tmp=fac[i]*pfac[j];
  48. int pos=lower_bound(fac+,fac++tot,tmp)-fac;
  49. if(fac[pos]==tmp&&una[pos]) {una[i]=true; break;}
  50. }
  51. for(int i=;i<=tot;i++)
  52. if(!una[i]) {printf("%lld",n/fac[i]); break;}
  53. return ;
  54. }

解题:POI 2011 Strongbox的更多相关文章

  1. 解题:POI 2011 Dynamite

    题面 从零开始的DP学习系列之叁 树形DP的基本(常见?)思路:先递归进儿子,然后边回溯边决策,设状态时常设$dp[x]$表示以$x$为根的子树中(具体分析算不算$x$这个点)的情况 显然的二分答案, ...

  2. 【BZOJ 2216】【POI 2011】Lightning Conductor

    http://www.lydsy.com/JudgeOnline/problem.php?id=2216 学习了一下决策单调性. 这道题决策单调性比较明显,不详细证了. 对于一个决策i,如果在i之前的 ...

  3. 【BZOJ 2212】【POI 2011】Tree Rotations

    http://www.lydsy.com/JudgeOnline/problem.php?id=2212 自下而上贪心. 需要用权值线段树来记录一个权值区间内的出现次数. 合并线段树时统计逆序对的信息 ...

  4. bzoj 2276 [ Poi 2011 ] Temperature —— 单调队列

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2276 维护 l 递减的单调队列,队头的 l > 当前的 r 就出队,因为不能是连续一段 ...

  5. [ POI 2011 ] Party

    \(\\\) \(Description\) 给定一张 \(N\ (\ N\equiv 0\pmod{3}\ )\) 个节点,,\(M\)条边的图,并且保证该图存在一个大小至少为\(\frac{2}{ ...

  6. [ POI 2011 ] Dynamite

    \(\\\) \(Description\) 一棵\(N\)个节点的树,树上有\(M\)个节点是关键点,选出\(K\)个特殊点,使得所有关键点到特殊点的距离中最大的最小,输出最大值最小为多少. \(N ...

  7. 洛谷 P3515 [ POI 2011 ] Lightning Conductor —— 决策单调性DP

    题目:https://www.luogu.org/problemnew/show/P3515 决策单调性... 参考TJ:https://www.cnblogs.com/CQzhangyu/p/725 ...

  8. Solution -「POI 2011」「洛谷 P3527」MET-Meteors

    \(\mathcal{Description}\)   Link.   给定一个大小为 \(n\) 的环,每个结点有一个所属国家.\(k\) 次事件,每次对 \([l,r]\) 区间上的每个点点权加上 ...

  9. POI题解整合

    我也不知道为啥我就想把POI的题全都放到一篇blog里写完. POI 2005 SAM-Toy Cars 贪心,每次选下次出现最晚的. POI 2006 KRA-The Disks 箱子位置单调,所以 ...

随机推荐

  1. noip2018 D1T3 赛道修建

    题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 mm 条赛道. C 城一共有 nn 个路口,这些路口编号为 1,2,…,n1,2,…,n,有 n-1n−1 条适合于修建赛道的双向通 ...

  2. Visionpro介绍和下载安装视频教程

    ------------------------Halcon,Visionpro高清视频教程,点击下载视频--------------------------

  3. Windows10子系统安装ubuntu+kali渗透环境

    Windows10安装子系统ubuntu,安装完ubuntu后再安装katoolin才能使用kali. (katoolin渗透测试的Linux发行版,它可以让你在其他Linux发行版上使用Kali的全 ...

  4. 笨办法学Python - 习题8-10: Printing & Printing, Printing

    目录 1.习题 8: 打印,打印 2.习题 9: 打印,打印,打印 3.习题 10: 那是什么? 3.1.转义序列: 4.习题总结: 1.习题 8: 打印,打印 学习目标:继续学习 %r 的格式化输出 ...

  5. iOS 静态库生成(引用第三方SDK、开源库、资源包)

    一.静态库创建 打开Xcode, 选择File ----> New ---> Project  选择iOS ----> Framework & Library ---> ...

  6. Maven3 用Maven创建第一个web项目(2)servlet演示

    上一章用Maven新建了web项目成功后,本文演示在此基础上应用servlet. 1.首先修改pom.xml文件,添加servlet依赖 <project xmlns="http:// ...

  7. java中static使用之静态方法注意点

    1.静态方法可以直接调用同类中的静态成员,但是不能直接调用非静态成员,这是为什么呢?大家想一下,静态成员在对象创建之前就要写入内存,所以它在内存中是实实在在的存在的,而非静态还不存在内存中,所以不能调 ...

  8. 一个简单的加减乘除自动生成小程序升级版(JAVA)

    import java.util.Scanner; public class Suan { public static void main(String[] args) { int []b;//设置数 ...

  9. 在虚拟机中安装Ubuntu详细过程

    参考:http://blog.csdn.net/u013142781/article/details/50529030

  10. SOAP 缓存问题

    今天在进行soap调用老是出错,去其他人的机器上试下,就好了,下面是从网上找到的原因 一开始不知道还有SOAP缓存.因为类文件改变了,重新生成了WSDL文件,测试运行,竟然不能通过.给我的第一感觉是W ...