• BZOJ 2118 墨墨的等式


    2118: 墨墨的等式

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 2387  Solved: 936
    [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

    网上的题解看的人很晕,我开始完全没有往最短路上面去想,好吧根本就没有想233333

    我们考虑一下这个答案肯定是符合前缀和的性质的,也就是说如果用sum[i]表示当B<=i时有多少个符合条件的解,那么定有sum[i]=sum[i-1]+t;

    也就是说这道题我们求[L,R],就可以可以转化为[1,R]的结果减去[1,L-1]的结果

    首先对于任意一个ai,最后的结果都可以由k*ai+x来表示,如果没有ai的化,k就是0  

     x表示除了ai外剩下所有的a数组的总贡献对ai进行取模是多少    也就是x=Σak*xk(k!=i)

    因为对于任意一个都可以     我们选取最小的那个来算,令minn=min(a[i]);也就是取所有a[i]的最小值              (为什么选最小的最后我们分析复杂度的时候再讲)

    首先我们肯定x是小于minn的   我们既然选取了特定的ai也就是minn,那么x就是表示除了minn剩下的所有相加的和对minn取模的结果是多少

    我们只要找出能满足x的最小花费是多少就可以了

    建minn个点,dis[i]分别表示模minn意义下余i的能凑出的数最小为多少。对于每一个ai,从x向(x+ai)%minn连一条边权为ai的边。

    求最短路,则最后求得dis[i],计算一下就可以了。这个是建图代码

    for(int i=0;i<a[1];i++){
        for(int j=2;j<=n;j++){
          insert(i,(i+a[j])%a[1],a[j]);
        }
    }

    最后我门可以发现复杂度是minnlogminn,这就是我们为什么要选取最小的ai的原因 

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    inline ll read(){
        ll x=-0;int f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int MAXN=1e6+10;
    struct node{
        int y,next,v;
    }e[MAXN<<3];
    ll linkk[MAXN],len=0,a[MAXN],dis[MAXN],vis[MAXN],n;
    typedef pair <ll,ll> pii;
    priority_queue < pii,vector<pii>,greater<pii> > q;
    inline void insert(ll xx,ll yy,ll vv){
        e[++len].y=yy;e[len].next=linkk[xx];e[len].v=vv;linkk[xx]=len;
    }
    void dijsktra(){
        q.push(make_pair(0,0));
        dis[0]=0;
        while(!q.empty()){
            ll tn=q.top().second;q.pop();
            if(vis[tn]) continue;
            vis[tn]=1;
            for(int i=linkk[tn];i;i=e[i].next){
                if(dis[tn]+e[i].v<dis[e[i].y]){
                    dis[e[i].y]=dis[tn]+e[i].v;
                    q.push(make_pair(dis[e[i].y],e[i].y));
                }
            }
        }
    }
    inline bool mycmp(int x,int y){
        return x>y;
    }
    int main(){
        //freopen("All.in","r",stdin);
        //freopen("zh.out","w",stdout);
        n=read();ll L=read();ll R=read();
        memset(dis,127,sizeof(dis));
        for(int i=1;i<=n;i++){
            a[i]=read();
        }
        sort(a+1,a+n+1);
        for(int i=0;i<a[1];i++){
            for(int j=2;j<=n;j++){
                insert(i,(i+a[j])%a[1],a[j]);
            }
        }
        dijsktra();
        ll ans=0;
        for(int i=0;i<a[1];i++){
            if(R>=dis[i]) ans+=(R-dis[i])/a[1]+1;
            if(L-1>=dis[i]) ans-=(L-dis[i]-1)/a[1]+1;
        }
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    appium的python异常处理
    appium环境搭建
    什么是Capability
    移动端自动化测试-WTF Appium
    python-selenium,关于页面滑动
    接口测试的要点
    共享文件夹在本机桌面创建快捷方式
    hosts文件失效,配置的域名不能成功访问
    隔一段时间应用就会挂掉(进程在,但停止响应,也无log输出),必须重启tomcat
    在同步方法中调用异步方法时如何避免死锁问题
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/8026137.html
Copyright © 2020-2023  润新知