• 2118: 墨墨的等式


    2118: 墨墨的等式

    https://www.lydsy.com/JudgeOnline/problem.php?id=2118

    分析:

      最短路。

      题意就是判断[L,R]内多少数,可以被许多个a1,a2,a3...构成。设最小的Mi = min{ai}。L,R<=1e12

      直接枚举肯定超时,那么换个方法枚举。

      考虑一个能构成的数b,它一定可以分解为$b = k imes M_i + r, r<M_i$。而且$b + M_i$也是可以构成的。所以我们可以找到最小的%Mi=r的数,比它大的%Mi=r的数可以直接算了。

      考虑如何计算最小的,%Mi=r的数:建一张无向图,共Mi个点,u表示%Mi=u点。dis[u]为最小的%Mi=u的数。那么可以跑最短路处理处dis[u](即我们要求的)。

      然后就可以直接计算了。可以计算出小于等于R的减去小于等于L-1的。

      设$dis[r]=k imes Mi + r$,那么小于等于R的就是$(R-dis[r])/M_i+1$,就是k可以是多少。

    代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<cctype>
     7 #include<set>
     8 #include<vector>
     9 #include<queue>
    10 #include<map>
    11 using namespace std;
    12 typedef long long LL;
    13 
    14 inline int read() {
    15     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    16     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    17 }
    18 
    19 const LL INF = 1e18;
    20 int a[20], n, Mi = 1e9;
    21 LL dis[500005];
    22 bool vis[500005];
    23 
    24 #define pa pair<LL,int>
    25 #define mp(a,b) make_pair(a,b)
    26 
    27 priority_queue< pa, vector< pa >, greater< pa > > q;
    28 
    29 void Dijkstra() {
    30     for (int i=0; i<Mi; ++i) 
    31         dis[i] = INF, vis[i] = false;
    32     q.push(mp(dis[0] = 0, 0));
    33     while (!q.empty()) {
    34         int u = q.top().second; q.pop();
    35         if (vis[u]) continue;
    36         vis[u] = true;
    37         for (int i=1; i<=n; ++i) {
    38             int v = (u + a[i]) % Mi;
    39             if (dis[v] > dis[u] + a[i]) {
    40                 dis[v] = dis[u] + a[i];
    41                 q.push(mp(dis[v], v));
    42             }
    43         }
    44     }
    45 }
    46 LL Calc(int i,LL x) {
    47     if (dis[i] > x) return 0;
    48     x -= dis[i];
    49     return x / Mi + 1;    
    50 }
    51 int main() {
    52     LL L, R;
    53     cin >> n >> L >> R;
    54     for (int i=1; i<=n; ++i) cin >> a[i], Mi = min(Mi, a[i]);
    55     Dijkstra();
    56     LL Ans = 0;
    57     for (int i=0; i<Mi; ++i) 
    58         if (dis[i] <= R) 
    59             Ans += Calc(i, R) - Calc(i, L - 1); 
    60     cout << Ans;
    61     return 0;
    62 }
  • 相关阅读:
    Selenium快速入门(下)
    Selenium快速入门(上)
    Python中yield和yield from的用法
    Python多进程
    Spring Cloud微服务安全实战_3-5_API安全之常见问题
    Spring Cloud微服务安全实战_3-3_API安全之流控
    Spring Cloud微服务安全实战_3-2_第一个API及注入攻击防护
    Spring Cloud微服务安全实战_3-1_API安全 常见的安全机制
    Spring Cloud微服务安全实战_2-1_开发环境
    Spring Cloud微服务安全实战_1-1_导学
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9708755.html
Copyright © 2020-2023  润新知