[bzoj2118]墨墨的等式dijk+堆
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[bzoj2118]墨墨的等式dijk+堆相关的知识,希望对你有一定的参考价值。
编译器真是神经了 k=k*2打成了k*2居然都不报错 还一点事情没有
害我改一晚上
一开始忘记了c++的数组默认从0开始
后来又把dijk写T了。。。。。重申一遍,这里是先把所有点加进去然后依次pop()
至于这道题,大家都说它是一道数论好题
而狗王一定要把它当作spfa专题来讲给小朋友们听
---erh。。。
网上题解有很多 首推po姐的
#include<cstdio> #define ll long long #define inf 1<<29 #include<algorithm> #include<iostream> #define N 500100 #include<cstring> using namespace std; int n,q[N],pos[N];ll a[N],f[N];ll bmin,bmax; int top; void push_up(int kk) { int k=kk; while(k/2>0&&f[q[k]]<f[q[k/2]]) { pos[q[k]]=k/2;pos[q[k/2]]=k; swap(q[k],q[k/2]); k/=2; } } void push_down() { int k=1; while(k*2<=top) { if(k*2+1<=top&&f[q[k]]>f[q[k*2+1]]&&f[q[k*2+1]]<f[q[k*2]]) { pos[q[k]]=k*2+1;pos[q[k*2+1]]=k; swap(q[k],q[k*2+1]); k=k*2+1; }else if(f[q[k]]>f[q[k*2]]) { pos[q[k]]=k*2;pos[q[k*2]]=k; swap(q[k],q[k*2]); k=k*2; }else break; } } void ins(int x) { top++;q[top]=x;pos[x]=top;push_up(top); } void dijk() { for(int i=0;i<a[1];i++)f[i]=inf; f[0]=0;for(int i=0;i<a[1];i++)ins(i); while(top) { int u=q[1];q[1]=q[top];top--; pos[q[1]]=1;push_down(); for(int i=2;i<=n;i++) if(f[(u+a[i])%a[1]]>f[u]+(u+a[i])/a[1]) { f[(u+a[i])%a[1]]=f[u]+(u+a[i])/a[1]; int xx=(u+a[i])%a[1]; push_up(pos[xx]); } } } ll max(ll a,ll b) { if(a>b)return a;else return b; } long long calc(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() { scanf("%d%lld%lld",&n,&bmin,&bmax); for(int i=1;i<=n;i++)scanf("%lld",&a[i]); dijk(); printf("%lld\\n",calc(bmax)-calc(bmin-1)); }
这里是一个很懒的博主。。。相信po姐大家都知道我就不贴传送门了yep
以上是关于[bzoj2118]墨墨的等式dijk+堆的主要内容,如果未能解决你的问题,请参考以下文章