zoukankan      html  css  js  c++  java
  • 「APIO 2019」奇怪装置

    题目

    考虑推柿子

    最开始的想法是如果两个(t)(mod B)意义下相等,那么只需要比较一下((t+left lfloor frac{t}{B} floor ight)mod A)就好了

    显然(t=t\% B+B imes lfloor frac{t}{B} floor)

    于是第一维就是$t%B+(B+1) imes lfloor frac{t}{B} floor $

    也就是说如果(t\%B)的是相等的,那么只要((B+1) imes lfloor frac{t}{B} floor)(mod A)意义下是相等的,那么两个(t)就是本质相同的

    考虑求一下后面那个东西的循环节,显然是(frac{lcm(B+1,A)}{B+1}=frac{A}{gcd(b+1,A)})

    再考虑到(t\%B)的循环节是(B),所以整个的循环节就是(frac{AB}{gcd(B+1,A)}),也就是说(t)(t+frac{AB}{gcd(B+1,A)})是本质相同的

    由此我们把这个问题转化成了一个(mod frac{AB}{gcd(B+1,A)})意义的区间覆盖,我们只需要把这些区间放上去覆盖就好了,最后就是求一下被覆盖的总面积,这个是一个非常普及的贪心问题

    非常丢人的写错了区间覆盖

    代码

    #include <bits/stdc++.h>
    #define re register
    #define max std::max
    #define LL long long
    inline LL read() {
        LL x = 0;char c = getchar();
        while (c < '0' || c > '9') c = getchar();
        while (c >= '0' && c <= '9') x = (x << 3ll) + (x << 1ll) + c - 48, c = getchar();
        return x;
    }
    int n, m;
    LL A, B, L;
    const int maxn = 1e6 + 5;
    struct Seg {LL l, r;} a[maxn], b[maxn << 1];
    LL gcd(LL a, LL b) { return !b ? a : gcd(b, a % b); }
    inline void add(LL x, LL y) { b[++m].l = x, b[m].r = y; }
    inline int cmp(Seg A, Seg B) { return A.l == B.l ? A.r > B.r : A.l < B.l; }
    int main() {
        n = read(), A = read(), B = read();
        for (re int i = 1; i <= n; i++) a[i].l = read(), a[i].r = read();
        for (re int i = 1; i <= n; i++) L = max(L, a[i].r);L++;
        LL r = gcd(A, B + 1);
        if (A / r <= L / B) L = A / r * B;
        for (re int i = 1; i <= n; i++) {
            LL x = a[i].r / L - a[i].l / L;
            if (x >= 2) {add(0, L - 1);break;}
            if (x == 1)
                add(0, a[i].r % L), add(a[i].l % L, L - 1);
            else
                add(a[i].l % L, a[i].r % L);
        }
        std::sort(b + 1, b + m + 1, cmp);
        int p = 1;LL ans = 0;
        for (re int i = 1; i <= m; i = p) {
            LL T = b[i].r;
            while (b[p].l <= T && p <= m) T = max(T, b[p].r), p++;
            ans += T - b[i].l + 1;
        }
        printf("%lld
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    15.RDD 创建内幕解析
    14.spark RDD解密
    我的读书笔记-《异类》
    深入解析单例线程安全问题的迷思
    一个关于数学归纳法的悖论问题-续
    一个关于数学归纳法的悖论问题
    简易解说拉格朗日对偶(Lagrange duality)(转载)
    unity3d NavMeshAgent 寻路画线/画路径
    unity3d easytouch计算摇杆旋转角度以及摇杆八方向控制角色
    unity3d 摄像机跟随角色时被物体遮挡解决方案
  • 原文地址:https://www.cnblogs.com/asuldb/p/11091396.html
Copyright © 2011-2022 走看看