BZOJ 2118 墨墨的等式 堆优化Dijkstra
2015-06-23 14:40
471 查看
题目大意:给定nn个物品,每个物品有一个非负价值,问[L,R][L,R]区间内有多少价值可以被凑出来
好题!!!
如果物品数量可以为负,显然求个gcdgcd就行了
现在物品数量必须非负
任选一个ai>0a_i>0,如果一个价值k∗ai+x(0≤x<ai,k≥0)k*a_i+x(0\leq x可以被凑出来,那么显然(k+1)∗ai+x,(k+2)∗ai+x,...(k+1)*a_i+x,(k+2)*a_i+x,...都可以被凑出来
显然如果我们对于每个xx都找到最小的kk满足k∗ai+xk*a_i+x可以被凑出来,这个问题就解决了
那么怎么求呢?最短路,使用堆优化Dijkstra即可
时间复杂度O(n∗ai∗log2ai)O(n*a_i*log_2a_i)
……数据范围错了,0≤ai≤5∗1050\leq a_i\leq 5*10^5
好题!!!
如果物品数量可以为负,显然求个gcdgcd就行了
现在物品数量必须非负
任选一个ai>0a_i>0,如果一个价值k∗ai+x(0≤x<ai,k≥0)k*a_i+x(0\leq x可以被凑出来,那么显然(k+1)∗ai+x,(k+2)∗ai+x,...(k+1)*a_i+x,(k+2)*a_i+x,...都可以被凑出来
显然如果我们对于每个xx都找到最小的kk满足k∗ai+xk*a_i+x可以被凑出来,这个问题就解决了
那么怎么求呢?最短路,使用堆优化Dijkstra即可
时间复杂度O(n∗ai∗log2ai)O(n*a_i*log_2a_i)
……数据范围错了,0≤ai≤5∗1050\leq a_i\leq 5*10^5
[code]#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 500500 using namespace std; int n; long long A,B; int a[M]; long long f[M]; namespace Heap{ int heap[M],pos[M],top; void Push_Up(int t) { while(t>1) { if( f[heap[t]]<f[heap[t>>1]] ) swap(heap[t],heap[t>>1]),swap(pos[heap[t]],pos[heap[t>>1]]),t>>=1; else break; } } void Insert(int x) { heap[++top]=x; pos[x]=top; Push_Up(top); } void Pop() { heap[1]=heap[top--]; pos[heap[1]]=1; int t=2; while(t<=top) { if( t<top && f[heap[t+1]]<f[heap[t]] ) ++t; if( f[heap[t]]<f[heap[t>>1]] ) swap(heap[t],heap[t>>1]),swap(pos[heap[t]],pos[heap[t>>1]]),t<<=1; else break; } } } void Dijkstra() { using namespace Heap; int i; memset(f,0x3f,sizeof f); f[0]=0; for(i=0;i<a[1];i++) Insert(i); while(top) { int x=heap[1];Pop(); for(i=2;i<=n;i++) if(f[(x+a[i])%a[1]]>f[x]+(x+a[i])/a[1]) { f[(x+a[i])%a[1]]=f[x]+(x+a[i])/a[1]; Push_Up(pos[(x+a[i])%a[1]]); } } } long long Calculate(long long x) { int i; long long re=0; for(i=0;i<a[1];i++) re+=max(0ll,x/a[1]+(x%a[1]>=i)-f[i]); return re; } int main() { int i; cin>>n>>A>>B; for(i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1); swap(a[1],a ); if(!a[1]) return cout<<0<<endl,0; Dijkstra(); cout<<Calculate(B)-Calculate(A-1)<<endl; return 0; }
相关文章推荐
- Oracle的列转行函数:listagg()
- C#录制视频聊天
- java.lang.OutOfMemoryError: Java heap space错误和方法(集、转)
- ARM寄存器
- jdk:HashSet基于HashMap实现
- JPEG: Exif信息相关
- Download all Apple open source OS X files at once
- Download all Apple open source OS X files at once
- oracle 前滚和回滚
- vim1
- Oracle 改变向量和REDO记录
- Ubuntu 12.04下安装RabbitVCS,类似Windows的TortoiseSVN
- 笔记2:win7下 OpenCv2.4.3+Qt5.0.1版本的配置
- PHP数据库连接文件
- 对于TCP的TCB的相关疑惑???
- IOS Xcode 编译警告 Semantic Warnings
- C++ 12.4.5 类成员的显示初始化----数据成员都是public类型且没有构造函数的类
- Oracle 11g 手工建库
- 自相关函数
- [数据结构]纸牌游戏——小猫钓鱼