• 4542: [Hnoi2016]大数


    4542: [Hnoi2016]大数

    链接

    分析:

      如果p等于2或者5,可以根据最后一位直接知道是不是p的倍数,所以直接记录一个前缀和即可。

      如果p不是2或者5,那么一个区间是p的倍数,当且仅当$frac{b[l] - b[r + 1]}{10 ^ {r - l + 1}} = 0 (mod p)$。

      由于p不是2或者5,所以10与p互质,条件转化为$b[r] - b[l] = 0 (mod p)$ ,于是将b离散化后,莫队即可。
    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 100005;
    int p;
    char s[N];
    namespace BF1{
        LL s1[N], s2[N];
        void solve() {
            scanf("%s",s + 1);
            int n = strlen(s + 1);
            for (int i = 1; i <= n; ++i) {
                s1[i] = s1[i - 1], s2[i] = s2[i - 1];
                if ((s[i] - '0') % p == 0) s1[i] ++, s2[i] += i;
            }
            int m = read();
            while (m --) {
                int l = read(), r = read();
                printf("%lld
    ", s2[r] - s2[l - 1] - 1ll * (l - 1) * (s1[r] - s1[l - 1]));
            }
        }
    }
    namespace BF2{
        struct Que{ int l, r, bel, id; } Q[N];
        bool operator < (const Que &A,const Que &B) { return A.bel == B.bel ? A.r < B.r : A.bel < B.bel; }
        int a[N], cnt[N];
        LL ans[N], b[N], disc[N];
        void solve() {
            scanf("%s", s + 1);
            int n = strlen(s + 1), B = sqrt(n);
            for (int i = n, pw = 1; i >= 1; --i, pw = 1ll * pw * 10 % p) // 开long long
                disc[i] = b[i] = (1ll * (s[i] - '0') * pw % p + b[i + 1]) % p;
            disc[n + 1] = 0;
            sort(disc + 1, disc + n + 2);
            int tot = 1;
            for (int i = 2; i <= n + 1; ++i) if (disc[i] != disc[tot]) disc[++tot] = disc[i];
            for (int i = 1; i <= n + 1; ++i) a[i] = lower_bound(disc + 1, disc + tot + 1, b[i]) - disc;
            int m = read();
            for (int i = 1; i <= m; ++i) 
                Q[i].l = read(), Q[i].r = read() + 1, Q[i].bel = (Q[i].l - 1) / B + 1, Q[i].id = i;
            sort(Q + 1, Q + m + 1);
            int L = 1, R = 0; LL now = 0;
            for (int i = 1; i <= m; ++i) {
                while (L > Q[i].l) L --, now += cnt[a[L]], cnt[a[L]] ++;
                while (R < Q[i].r) R ++, now += cnt[a[R]], cnt[a[R]] ++;
                while (L < Q[i].l) cnt[a[L]] --, now -= cnt[a[L]], L ++;
                while (R > Q[i].r) cnt[a[R]] --, now -= cnt[a[R]], R --;
                ans[Q[i].id] = now;
            }
            for (int i = 1; i <= m; ++i) printf("%lld
    ", ans[i]);        
        }
    }
    int main() {
        p = read();
        if (p == 2 || p == 5) BF1::solve();
        else BF2::solve();
        return 0;
    }
  • 相关阅读:
    Activity与Fragment间的通信
    Activity生命周期.lanchMode.保存状态
    网络知识
    Android内存优化(使用SparseArray和ArrayMap代替HashMap)
    进程/线程死锁产生的原因以及如何避免死锁
    Android UI框架基本概念
    android在线源码
    y音频学习
    给 Android 开发者的 RxJava 详解
    设计模式之观察者模式
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10472071.html
Copyright © 2020-2023  润新知