[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

时间: 2024-10-11 14:33:16

[bzoj2118]墨墨的等式【dijk+堆】的相关文章

bzoj2118 墨墨的等式

2118: 墨墨的等式 Time Limit: 10 Sec  Memory Limit: 259 MB Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+-+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. Input 输入的第一行包含3个正整数,分别表示N.BMin.BMax分别表示数列的长度.B的下界.B的上界.输入的第二行包含N个整数,即数列{an}的值. Output 输出一个

BZOJ2118墨墨的等式[数论 最短路建模]

2118: 墨墨的等式 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1317  Solved: 504[Submit][Status][Discuss] Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. Input 输入的第一行包含3个正整数,分别表示N.BMin.BMax分别表示数

【BZOJ 2118】 2118: 墨墨的等式 (最短路)

2118: 墨墨的等式 Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+-+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. Input 输入的第一行包含3个正整数,分别表示N.BMin.BMax分别表示数列的长度.B的下界.B的上界.输入的第二行包含N个整数,即数列{an}的值. Output 输出一个整数,表示有多少b可以使等式存在非负整数解. Sample Input 2 5 1

BZOJ 2118: 墨墨的等式

2118: 墨墨的等式 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1656  Solved: 650[Submit][Status][Discuss] Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. Input 输入的第一行包含3个正整数,分别表示N.BMin.BMax分别表示数

数论+spfa算法 bzoj 2118 墨墨的等式

2118: 墨墨的等式 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1283  Solved: 496 Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. Input 输入的第一行包含3个正整数,分别表示N.BMin.BMax分别表示数列的长度.B的下界.B的上界.输入的第二行包含N个

2118: 墨墨的等式

2118: 墨墨的等式 https://www.lydsy.com/JudgeOnline/problem.php?id=2118 分析: 最短路. 题意就是判断[L,R]内多少数,可以被许多个a1,a2,a3...构成.设最小的Mi = min{ai}. 直接枚举肯定超时,那么换个方法枚举. 考虑一个能构成的数b,它一定可以分解为$b = k \times M_i + r, \ r<M_i$.而且$b + M_i$也是可以构成的.所以我们可以找到最小的%Mi=r的数,比它大的%Mi=r的数可以

【bzoj2118】 墨墨的等式

http://www.lydsy.com/JudgeOnline/problem.php?id=2118 (题目链接) 题意 给出B的取值范围[Bmin,Bmax],求方程a1x1+a2x2+…+anxn=B有多少B可以使等式存在非负整数解. Solution 问题很容易就被转化为:用a1,a2,a3,······an能组成多少个在范围[Bmin,Bmax]内的数.这是一类经典的图论问题. 我们假设a[]中最小的元素为T,可以考虑用n个数能够组成的数对T的模的情况.用dis[i]表示构成的一个数

BZOJ 2118 墨墨的等式 堆优化Dijkstra

题目大意:给定n个物品,每个物品有一个非负价值,问[L,R]区间内有多少价值可以被凑出来 好题!!! 如果物品数量可以为负,显然求个gcd就行了 现在物品数量必须非负 任选一个ai>0,如果一个价值k?ai+x(0≤x<ai,k≥0)可以被凑出来,那么显然(k+1)?ai+x,(k+2)?ai+x,...都可以被凑出来 显然如果我们对于每个x都找到最小的k满足k?ai+x可以被凑出来,这个问题就解决了 那么怎么求呢?最短路,使用堆优化Dijkstra即可 时间复杂度O(n?ai?log2ai)

BZOJ 2118 墨墨的等式(最短路)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2118 [题目大意] 求a1x1+a2y2+…+anxn=B在B的取值范围,有多少B可以使等式存在非负整数解. [题解] 同余最短路,不等式解集计数即可. [代码] #include <cstdio> #include <algorithm> #include <queue> using namespace std; const int N=500010; n