您的位置:首页 > 其它

BZOJ 2118: 墨墨的等式

2017-04-07 16:51 381 查看
这道题太TM神了。。智商被虐啊 好题啊!

找一个ai,若x为合法的B,则x+ai也合法

设bi为最小的x,满足x mod mn = i

求出每个bi就可以求答案了

bi用最短路求就好了啊 意会一下

最后枚举余数搞一下就算出答案了

代码好短啊2333

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=500002;
inline LL read(){
char ch=getchar(); LL x=0;
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0'; ch=getchar();}
return x;
}
struct g{
LL w;int x;
bool operator <(g a)const{return w>a.w;}
};
struct u{int y;LL c;int next;}a[12*N]; int len,first
;
void ins(int x,int y,LL c){a[++len]=(u){y,c,first[x]},first[x]=len;}
int o[13]; LL d
;
priority_queue<g>q;
int main()
{
int n=read(),i,j,mn=1e6; LL b1=read(),b2=read();
for(i=1;i<=n;i++)o[i]=read(),mn=o[i]<mn?o[i]:mn;
for(i=1;i<mn;i++)d[i]=1e15;
for(i=1;i<=n;i++)
if(o[i]%mn){
int _=o[i]%mn;
for(j=0;j<mn;j++)ins(j,(j+_)%mn,o[i]);
}
q.push((g){0,0});
while(!q.empty()){
g r=q.top(); q.pop(); int x=r.x;
if(r.w!=d[x])continue;
for(int k=first[x];k;k=a[k].next){
int y=a[k].y;
if(d[y]>d[x]+a[k].c)q.push((g){d[y]=d[x]+a[k].c,y});
}
}
LL ans=0;
for(i=0;i<mn;i++)if(d[i]<=b2){
LL l=max(0ll,(b1-d[i])/mn);
if(l*mn+d[i]<b1)l++;
LL r=(b2-d[i])/mn;
ans+=r-l+1;
}
printf("%lld\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: