洛谷P4571 [JSOI2009] 瓶子和燃料
题目
https://www.luogu.com.cn/problem/P4571
思路
首先观察并且简单模拟一下火星人取燃料的过程,发现最终燃料的量一定是他选的k个瓶子容量的线性组合(观察操作3就知道)。火星人的抠门,就是说他会找到这些线性组合当中最小的正整数结果\(y\)。
让我们用式子描述一下,设k个瓶子的容量分别为\(x_1,x_2,...x_k\),那么有不定方程\(a_1x_1+a_2x_2+...+a_kx_k=y\),我们要求的就是使方程有解的最小的\(y\)。
然后根据裴蜀定理,\(y_{min}=gcd(x_1,x_2,...,x_k)\),题目就变成了要选k个数使得他们gcd值最大。
先不考虑时间复杂度,看看怎么保证正确性,首先gcd一定是某个\(a[i]\)的因数,那我们就对每个\(a[i]\)求一遍因数,然后该因数所对应的计数器++(我们先不考虑怎样计数)。最后查一下计数器\(\geq k\)的值。
考虑下总共有多少因数,一个数的除数函数\(\sigma_0(a)\)有个不紧的上界\(2\sqrt a\),总共1000个数,每个数因数个数小于1e5(事实上肯定远远小于),所以我们写个哈希再开个数组计数就行了。
然后就是时间复杂度的问题。求一个数的因数要实打实的\(\sqrt a\),总计是\(10^8\)级别,就很容易挂,得想办法优化一下。
①对于质数,它只有本身是有贡献的,根本不用继续试除,我们写个miller_rabin把素数判掉。
②维护一个全局ans值保存当前最大合法gcd值,如果在试除过程中不可能再有因子大于ans了就跳出。
③预先将a数组大到小排序,可能有助于提前找到很大的最优解。
加了这几个优化之后跑得飞快(287ms)。

代码
点击查看代码
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
int prime[10]={0,2,3,5,7,11};
int n,k,ans=0;
int a[1010];
const int zzd=233333;
struct Hashmap{
int fst[zzd],nxt[1000000],cnt,val[1000000];
Hashmap(){cnt=0;}
int insert(int x){
nxt[++cnt]=fst[x%zzd];
val[cnt]=x;
fst[x%zzd]=cnt;
return cnt;
}
int find(int y){
int i=fst[y%zzd];
while(i){
if(val[i]==y) return i;
i=nxt[i];
}
return 0;
}
} H;
int c[1000000];
ll qpow(ll x,ll p,ll m){
ll ans=1,base=x;
for(;p;p>>=1){
if(p&1) ans=ans*base%m;
base=base*base%m;
}
return ans;
}
int miller_rabin(ll x){
if(x==1) return 0;
ll y=x-1;
int i,j,u=0;
while(!(y&1ll)) y>>=1,u++;
for(i=1;i<=5;++i){
if(x==prime[i]) return 1;
if(!(x%prime[i])) return 0;
ll q=qpow(prime[i],y,x);
for(j=0;j<=u;++j){
if((q*q)%x==1&&q!=1&&q!=x-1) return 0;
if(j==u&&q!=1) return 0;
q=q*q%x;
}
}
return 1;
}
bool cmp(ll x,ll y){
return x>y;
}
void dec(int y){
int i,z;
int x=y,lim=(int)sqrt(x)+1;
for(i=1;i<=lim;++i){
if(x%i) continue;
if(x/i<=ans) break;
z=H.find(i);
if(!z) z=H.insert(i);
if(++c[z]>=k) ans=max(ans,i);
z=H.find(x/i);
if(!z) z=H.insert(x/i);
if(++c[z]>=k) ans=max(ans,x/i);
if(i==1&&miller_rabin(x)) break;
}
return;
}
int main(){
int i,j;
scanf("%d%d",&n,&k);
for(i=1;i<=n;++i) scanf("%d",&a[i]);
sort(a+1,a+n+1,cmp);
for(i=1;i<=n;++i){
if(a[i]<=ans) break;
dec(a[i]);
}
printf("%d",ans);
// system("pause");
return 0;
}
洛谷P4571 [JSOI2009] 瓶子和燃料的更多相关文章
- 洛谷 P4571 BZOJ 2257 [JSOI2009]瓶子和燃料
bzoj题目链接 上面hint那里是选择第2个瓶子和第3个瓶子 Time limit 10000 ms Memory limit 131072 kB OS Linux Source Jsoi2009 ...
- 【BZOJ2257】[JSOI2009]瓶子和燃料(数论)
[BZOJ2257][JSOI2009]瓶子和燃料(数论) 题面 BZOJ 洛谷 题解 很明显就是从\(n\)个数里面选\(K\)个数让他们的\(gcd\)最大. 暴力找所有数的因数,拿个什么东西存一 ...
- BZOJ 2257: [Jsoi2009]瓶子和燃料 裴蜀定理
2257: [Jsoi2009]瓶子和燃料 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
- bzoj2257 [Jsoi2009]瓶子和燃料 最大公约数
[Jsoi2009]瓶子和燃料 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1449 Solved: 889[Submit][Status][Di ...
- BZOJ 2257: [Jsoi2009]瓶子和燃料【数论:裴蜀定理】
2257: [Jsoi2009]瓶子和燃料 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1326 Solved: 815[Submit][Stat ...
- bzoj2257: [Jsoi2009]瓶子和燃料
2257: [Jsoi2009]瓶子和燃料 Time Limit: 10 Sec Memory Limit: 128 MB Description jyy就一直想着尽快回地球,可惜他飞船的燃料不够了 ...
- [BZOJ 2257][JSOI2009]瓶子和燃料 题解(GCD)
[BZOJ 2257][JSOI2009]瓶子和燃料 Description jyy就一直想着尽快回地球,可惜他飞船的燃料不够了. 有一天他又去向火星人要燃料,这次火星人答应了,要jyy用飞船上的瓶子 ...
- [JSOI2009]瓶子和燃料
Description jyy就一直想着尽快回地球,可惜他飞船的燃料不够了. 有一天他又去向火星人要燃料,这次火星人答应了,要jyy用飞船上的瓶子来换.jyy 的飞船上共有 N个瓶子(1<=N& ...
- [JSOI2009]瓶子和燃料 BZOJ2257 数学
题目描述 jyy就一直想着尽快回地球,可惜他飞船的燃料不够了.有一天他又去向火星人要燃料,这次火星人答应了,要jyy用飞船上的瓶子来换.jyy的飞船上共有 N个瓶子(1<=N<=1000) ...
- 【数学 裴蜀定理】bzoj2257: [Jsoi2009]瓶子和燃料
使gcd最大的trick Description jyy就一直想着尽快回地球,可惜他飞船的燃料不够了. 有一天他又去向火星人要燃料,这次火星人答应了,要jyy用飞船上的瓶子来换.jyy的飞船上共有 N ...
随机推荐
- centos7端口转发工具rinetd
1.下载软件 wget http://li.nux.ro/download/nux/misc/el7/x86_64/rinetd-0.62-9.el7.nux.x86_64.rpm 2.安装软件 yu ...
- P1046 [NOIP2005 普及组] 陶陶摘苹果
题目描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出 10 个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个 30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试. 现在已 ...
- 【Python】【算法】【排序】用Python实现排序的三种算法
class SortTest: def __init__(self): pass # 冒泡排序 def BubbleSort(self, value): if isinstance(value, li ...
- 2015 for Mac PDF编辑软件
开始前请先断开网络连接,断网,断网,断网! 开始前请先断开网络连接,断网,断网,断网! 开始前请先断开网络连接,断网,断网,断网! 编辑 1.软件下载完成后,打开软件包如上图五个文件(第1个是安 ...
- Web安全与渗透测试笔记
Web安全与渗透测试笔记 @author: lamaper 一.基本网络知识 (一)网络是怎样联通的 TCP/IP协议 Internet Http协议 (二)Http协议 http请求 一个完整的Ht ...
- TM1621断码液晶驱动IC的原理、驱动代码
TM1621是一个多功能的LCD驱动器,带有蜂鸣器驱动功能.通讯采用四线串行接口 TM1621的难点在于字节序和显存跟屏幕的映射关系上,下面是写寄存器的代码 void Delay_us(uint8_t ...
- 【windows】 进程间通信 WM_COPYDATA消息
WM_COPYDATA消息可以实现window应用程序之间的数据传输,是同步传输方式. 需要用到结构体 COPYDATASTRUCT typedef struct tagCOPYDATASTRUCT ...
- php functions 生成唯一码
<?php /** * 微擎密码生成 * */ function we7password($passwordinput, $salt, $authkey) { $passwordinput = ...
- C#常见的数据结构
数据结构:1.Set集合,纯粹的容器,无需存储,就是一个容器2.线型结构:在存储的时候,一对一存储3.树形结构:表达式目录树(二叉树).菜单结构:一对多4.图形结构:扩扑图.网状结构(地图开发,用C# ...
- KingbaseES V8R6备份恢复案例之---自定义表空间指定恢复目录数据恢复
案例说明: KingbaseES V8R6在通过sys_rman执行物理备份恢复时,可以通过参数'--kb1-path',指定恢复的数据(data)目录,但如果原备份中包含自定义表空间时,需要建立表空 ...