[POI2011]SEJ-Strongbox
题目大意:
一个有密码箱,数字是0~n-1,其中有若干个密码,密码的特点:若x是密码,y是密码,(x可以等于y)则(x+y)%n也是密码。
给一个n(<=10^14),一个k(k<=min(250000,n)),给k个数(a[k]<n),前k-1个数不是密码,第k个数是密码。
求在0~n-1中,最多有多少个数字是密码?
题解:
看起来和数论有一些关系。
而且一定是一个性质题。
结论1:若x是密码,则gcd(n,x)是密码
发现,x是密码,则k*x%n都是密码。
所以,一定存在一个t,c,使得t*x-n*c=gcd(n,x)
并且根据裴属定理,不能用x凑出一个更小的密码比gcd(n,x)更小,
结论2:若x,y是密码,则gcd(x,y)是密码。
根据裴属定理,p*x+q*y=gcd(x,y)有整数解。
如果q是负数q=-q,那么就是p*x+(c*n-q)*y=gcd(x,y)+c*n*y
那么,就存在非负数p,q使得p*x+q*y=gcd(x,y) mod n
结论3:若x是所有密码中最小的那一个,那么,所有的密码就是x,2x,3x,...kx,并且x是n的约数。
反证。设x是最小的,y是另一个密码,若x不是y的约数,那么gcd(x,y)<x,根据结论二,那么gcd(x,y)就是一个更小的密码。矛盾。
所以,任意的y都是x的倍数。
由于对于一个密码z,根据结论1,gcd(n,z)也是密码,所以,最小的密码x是gcd(n,z)的约数,也就是n的约数。
所以,如果我们求出了满足条件的x,那么n/x就是答案。
我们密码数量最多,所以,x必须取最小的。
由于给了一个a[k]是密码,而x又是n的约数,所以x就一定是gcd(a[k],n)的约数。
并且,x不能是a[1~k-1]的约数,只要是,那么x就能凑出ai,与ai不是密码矛盾。
只要不存在这样的ai,那么x一定可以是最小的密码(裴属定理可以证明)。
所以,我们可以枚举gcd(a[k],n)的约数,然后排序。
从小到大枚举x,再暴力验证是否是a[i]的约数,第一个符合的x,n/x就是答案。
O(ksqrt(n))
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=+;
ll n,k;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll a[N],fac[N];
int tot;
int main(){
scanf("%lld%lld",&n,&k);
for(int i=;i<=k;i++)scanf("%lld",&a[i]);
ll g=gcd(a[k],n);
//cout<<"gg "<<g<<endl;
for(ll i=;i*i<=g;i++){
if(g%i==){
fac[++tot]=i;
if(i!=g/i) fac[++tot]=g/i;
}
}sort(fac+,fac+tot+);
for(int i=;i<=tot;i++){
//cout<<fac[i]<<" ";
bool fl=true;
for(int j=;j<=k-;j++){
if(a[j]%fac[i]==){
fl=false;break;
}
}
if(fl){
printf("%lld",n/fac[i]);return ;
}
}
//cout<<" over "<<endl;
return ;
}
然而这个代码BZOJ过不去。
还要优化。
发现,每次对一个因数判断所有的k个数代价太大。
一个a[i]影响的是哪些gcd(a[k],n)的因数呢?
一定是gcd(a[i],a[k])的因数。
所以,我们可以把所有的gcd(a[i],a[k])的因数找出来干掉。
然后直接再扫一遍,找到最小的没有被干掉的因数即可。
复杂度?O(sqrt(n)+klogn+玄学)
代码:
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define ri register int
#define numb (ch^'0')
using namespace std;
typedef long long ll;
const int N=+;
void rd(ll &x){
x=;
char ch;
while(!isdigit(ch=getchar()));
for(x=numb;isdigit(ch=getchar());x=(x<<)+(x<<)+numb);
}
ll n,k;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll a[N],fac[N];
bool kil[N];
int tot;
int main(){
scanf("%lld%lld",&n,&k);
for(ri i=;i<=k;i++)scanf("%lld",&a[i]);
ll g=gcd(a[k],n);
for(ri i=;i<k;++i) a[i]=gcd(a[i],g);
for(ll i=;i*i<=g;i++){
if(g%i==){
fac[++tot]=i;
if(i!=g/i) fac[++tot]=g/i;
}
}sort(fac+,fac+tot+);
for(ri i=;i<k;i++){
kil[lower_bound(fac+,fac+tot+,a[i])-fac]=;
}
for(ri i=;i<=tot;++i){
if(kil[i]){
for(int j=;j<i;j++) {
if(fac[i]%fac[j]==) kil[j]=;
}
}
}
for(ri i=;i<=tot;++i){
if(!kil[i]) {
printf("%lld\n",n/fac[i]);
return ;
}
}
return ;
}
[POI2011]SEJ-Strongbox的更多相关文章
- bzoj 2277 [Poi2011]Strongbox 数论
2277: [Poi2011]Strongbox Time Limit: 60 Sec Memory Limit: 32 MBSubmit: 527 Solved: 231[Submit][Sta ...
- bzoj2277 [Poi2011]Strongbox
2277: [Poi2011]Strongbox Time Limit: 60 Sec Memory Limit: 32 MBSubmit: 498 Solved: 218[Submit][Sta ...
- BZOJ2277[Poi2011]Strongbox——数论
题目描述 Byteasar is a famous safe-cracker, who renounced his criminal activity and got into testing and ...
- [poi2011]bzoj 2277 —— strongbox·[洛谷3518]
·问题描述· 有一个密码箱,0到n-1中的某些数是它的密码.且满足:如果a和b都是它的密码,那么(a+b)%n也是它的密码.某人试了k次密码,前k-1次都失败了,最后一次成功. 问:该密码箱最多有多少 ...
- 【BZOJ】2277: [Poi2011]Strongbox
题意 有一个密码箱,\(0\)到\(n-1\)中的某些整数是它的密码.如果\(a\)和\(b\)都是它的密码,那么\((a+b)%n\)也是它的密码(\(a,b\)可以相等).某人试了\(k\)次密码 ...
- BZOJ 2277 Poi2011 Strongbox
题目大意:一个集合A,包含了0~n-1这n个数.另有一个集合B,满足: 1.B是A的子集. 2.如果a.b均在B中,则(a+b)%n也在B中(a=b亦可) 给出k个数ai,前k-1个不在B中,第k个在 ...
- BZOJ2277 [Poi2011]Strongbox 【数论】
题目链接 BZOJ2277 题解 orz太难了 如果一个数\(x\)是密码,那么所有\((x,n)\)的倍数都是密码 如果两个数\(x,y\)是密码,那么所有\((x,y)\)的倍数都是密码 那么如果 ...
- POI2011题解
POI2011题解 2214先咕一会... [BZOJ2212][POI2011]Tree Rotations 线段树合并模板题. #include<cstdio> #include< ...
- BZOJ2527: [Poi2011]Meteors
补一发题解.. 整体二分这个东西,一开始感觉复杂度不是很靠谱的样子 问了po姐姐,说套主定理硬干.. #include<bits/stdc++.h> #define ll long lon ...
- BZOJ2276: [Poi2011]Temperature
2276: [Poi2011]Temperature Time Limit: 20 Sec Memory Limit: 32 MBSubmit: 293 Solved: 117[Submit][S ...
随机推荐
- 利用Pillow给图片添加重点框(适用UI自动化测试)
效果图 一个简单的例子 安装Pillow 在cmd窗口/终端输入: pip install pillow 如果被墙,下载巨慢的话,可以临时替换豆瓣源 pip install pillow -i htt ...
- 240. 搜索二维矩阵 II
二维数组搜索 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上到下升序排列. 示例: 现有矩阵 ...
- Leetcode_2. Add_Two_Number
2. Add_Two_Number 用两个非空链表分别表示两个非负整数,链表的节点表示数字的位,链表头表示数字的低位,链表尾表示数字高位.求两个链表所表示数字的和. 比如: Input: (2 -&g ...
- 清空git缓存
git rm -r --cached .git add . git commit -m 'update .gitignore' 读了下git文档,才发现,这些东西其实很简单,很容易理解.cached其 ...
- OGNL动态实现result
OGNL就是struts.xml文件中的<result>通过get()方法,动态获取action类中的变量 <struts> <package name="de ...
- 博弈--ZOJ 3084 S-Nim(SG)
题意: 首先输入K 表示一个集合的大小 之后输入集合 表示对于这对石子只能去这个集合中的元素的个数 之后输入 一个m 表示接下来对于这个集合要进行m次询问 之后m行 每行输入一个n 表示有n个堆 ...
- Croc Champ 2013 - Round 1 E. Copying Data 线段树
题目链接: http://codeforces.com/problemset/problem/292/E E. Copying Data time limit per test2 secondsmem ...
- lintcode-407-加一
407-加一 给定一个非负数,表示一个数字数组,在该数的基础上+1,返回一个新的数组. 该数字按照大小进行排列,最大的数在列表的最前面. 样例 给定 [1,2,3] 表示 123, 返回 [1,2,4 ...
- 在原有的基础之上,启用NAT模型
# 给虚拟主机实例添加一个网关 route add default gw 192.168.23.1 # 在宿主机打开网卡间转发功能 echo 1 > /proc/sys/net/ipv4/i ...
- 使用命令virsh管理网络设备,创建桥设备 和 使用virt-manager创建虚拟机
# 1:查看网卡接口 virsh iface-list Name State MAC Address ------------------------------------------------- ...