BZOJ_P2118 墨墨的等式(最短路)

BZOJ傳送門

Time Limit: 10 Sec Memory Limit: 259 MB
Submit: 928 Solved: 356
[Submit][Status][Discuss]

Description
墨墨突然對等式很感興趣,他正在研究a1x1+a2y2+…+anxn=B存在非負整數解的條件,他要求你編寫一個程序,給定N、{an}、以及B的取值範圍,求出有多少B可以使等式存在非負整數解。

Input
輸入的第一行包含3個正整數,分別表示N、BMin、BMax分別表示數列的長度、B的下界、B的上界。輸入的第二行包含N個整數,即數列{an}的值。

Output
輸出一個整數,表示有多少b可以使等式存在非負整數解。

Sample Input
2 5 10
3 5

Sample Output
5

HINT
對於100%的數據,N≤12,0≤ai≤5*10^5,1≤BMin≤BMax≤10^12。

Source

Sol:
反正我不會建模QuQ,抄題解+1
因爲原等式係數不定,假定他們沒有限制,考慮同餘類。求出最小的a[i],如果x%a[i]=b可以得到那麼x+a[i]也可以得到
最短路建模,將在mod a[i]的條件下的每個餘數(其實就是[0,a[i]-1])與+每個其他數的節點連線,距離爲a[j] (詳細看代碼吧)
最後計算方案數,求[MIN,MAX]等價於求[1,MAX]-[1,MIN]如果在%a[i]意義下最小的d[i]<=K,那麼方案數就有(K-d[i])/a[i]+1,計算就可以了
QuQ我太弱了!

#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<iostream>
using namespace std;
#define N 500005
inline long long in(long long  x=0,char ch=getchar()){while(ch>'9'||ch<'0') ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x;}
struct Edge{int to;long long v;};vector<Edge> g[N];
int n,minv;long long MIN,MAX;int a[N];
long long d[N];long long ans;bool b[N];
struct Heap{int to;long long d;bool operator < (const Heap &a)const{return d>a.d;}};
void Dijkstra(){
    priority_queue<Heap> q;q.push((Heap){0,0});
    memset(d,0x7f,sizeof(d));d[0]=0;int x;
    while(!q.empty()){
        x=q.top().to;q.pop();
        if(b[x]) continue;b[x]=1;
        for(int i=0,v,lim=g[x].size();i<lim;i++){
            if(d[x]+g[x][i].v<d[v=g[x][i].to]){
                d[v]=d[x]+g[x][i].v;
                q.push((Heap){v,d[v]});
            }
        }
    }
}
int main(){
    n=in(),MIN=in()-1,MAX=in();minv=0x7fffffff;
    for(int i=1;i<=n;i++) a[i]=in(),minv=min(minv,a[i]);
    for(int i=0;i<minv;i++)
        for(int j=1;j<=n;j++) 
            if(a[j]%minv!=0) g[i].push_back((Edge){(i+a[j])%minv,a[j]});
    Dijkstra();
    for(int i=0;i<minv;i++){
        if(d[i]<=MIN) ans-=(MIN-d[i])/minv+1;
        if(d[i]<=MAX) ans+=(MAX-d[i])/minv+1; 
    }
    printf("%lld\n",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章