bzoj2118 分类: bzoj 2015-...


这题很有意思哦~


以最小的非零系数为模数,记为 M

如果存在 W 使方程有解,W 与 W’ 在模意义下同余并且 W < W’,那么 W’也使方程有解。

dist(i) 为满足 W mod M = i 时 W 的最小值,用最短路求出dist,然后计算答案就行了~


分别统计1~Wmax,1~Wmin-1中满足 W mod M=i 的W的个数

ans=M1i=0(count(Wmax,i)count(Wmin1,i))



#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <vector>
#include <utility>
#include <stack>
#include <queue>
#include <iostream>
#include <algorithm>

template<class Num>void read(Num &x)
{
    char c; int flag = 1;
    while((c = getchar()) < '0' || c > '9')
        if(c == '-') flag *= -1;
    x = c - '0';
    while((c = getchar()) >= '0' && c <= '9')
        x = (x<<3) + (x<<1) + (c-'0');
    x *= flag;
    return;
}
template<class Num>void write(Num x)
{
    if(x < 0) putchar('-'), x = -x;
    static char s[20];int sl = 0;
    while(x) s[sl++] = x%10 + '0',x /= 10;
    if(!sl) {putchar('0');return;}
    while(sl) putchar(s[--sl]);
}

typedef std::pair<long long,int> heapnode;
#define RootMin std::vector<heapnode>, std::greater<heapnode>
const int maxn = 15, size = 5e5+5, Nya = -1;

int n, a[maxn];
long long Bmin, Bmax, ans;

std::priority_queue<heapnode, RootMin> heap;

long long dist[size];
bool hash[size];

void Dijstra(int st)
{
    int p; long long d;

    for(int i = 1; i < a[n]; i++) dist[i] = Nya;
    dist[0] = 0, heap.push(std::make_pair(0, 0));

    while(!heap.empty())
    {
        int t = heap.top().second;
        heap.pop();

        if(hash[t]) continue;

        hash[t] = true;

        for(int i = 1; i < n; i++)
        {
            p = (t + a[i])%a[n], d = dist[t] + a[i];

            if(!hash[p] && (dist[p] == Nya || d < dist[p]))
                heap.push(std::make_pair((dist[p] = d), p));
        }
    }
    return;
}
long long Count(long long s,int t)
{   
    return std::max(0LL, s/a[n] + ((t <= s%a[n])?1:0) - dist[t]/a[n]);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("2118.in","r",stdin);
    freopen("2118.out","w",stdout);
#endif

    read(n), read(Bmin), read(Bmax);
    for(int i = 1; i <= n; i++) read(a[i]);

    std::sort(a + 1, a + n + 1);

    if(!a[n]) ans = 0;
    else
    {
        Dijstra(0);

        for(int i = 0; i < a[n]; i++)
            if(dist[i] != Nya)
            {
                ans += Count(Bmax, i);
                ans -= Count(Bmin - 1, i);
            }
    }
    write(ans);

#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
#endif
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://www.cnblogs.com/dashgua/p/4722962.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值