• 洛谷P3245 [HNOI2016]大数(莫队)


    题意

    题目链接

    Sol

    莫队板子题。。

    维护出每个位置开始的字符串(mod P)的结果,记为(S_i)

    两个位置(l, r)满足条件当且仅当(S_l - S_r = 0),也就是(S_l = S_r)

    离散化之后直接上莫队就行了

    (2, 5)特判一下,因为2/5是10的因子,可能导致答案变大。直接维护(0/5)的出现次数就可以了

    考场上一高兴写了三个Subtask。。

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int MAXN = 1e6 + 10;
    int mod;
    template <typename A, typename B>
    inline void mul2(A &x, B y) {
        x = 1ll * x * y % mod;
    }
    template <typename A, typename B>
    inline int mul(A x, B y) {
        return 1ll * x * y % mod;
    }
    template <typename A, typename B>
    inline int add(A x, B y) {
        return x + y >= mod ? x + y - mod : x + y;
    }
    inline int read() {
        char c = getchar();
        int x = 0, f = 1;
        while (c < '0' || c > '9') {
            if (c == '-')
                f = -1;
            c = getchar();
        }
        while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    int N, Q, belong[MAXN], block, l, r;
    LL now, ans[MAXN];
    char s[MAXN];
    
    namespace Sub3 {
    int pro[MAXN], num, date[MAXN], cnt[MAXN];
    void Des() {
        for (int i = 1; i <= N + 1; i++) date[++num] = pro[i];
        sort(date + 1, date + num + 1);
        num = unique(date + 1, date + num + 1) - date - 1;
        for (int i = 1; i <= N + 1; i++) pro[i] = lower_bound(date + 1, date + num + 1, pro[i]) - date;
    }
    struct Query {
        int l, r, id;
        bool operator<(const Query &rhs) const {
            return belong[l] == belong[rhs.l] ? r < rhs.r : belong[l] < belong[rhs.l];
        }
    } q[MAXN];
    void Add(int x) {
        now += cnt[x];
        cnt[x]++;
    }
    void Delet(int x) {
        cnt[x]--;
        now -= cnt[x];
    }
    void solve() {
        block = sqrt(N);
        for (int i = 1; i <= N; i++) belong[i] = (i - 1) / block + 1;
        for (int i = N, base = 1; i >= 1; i--, mul2(base, 10)) pro[i] = add(pro[i + 1], mul((s[i] - '0'), base));
        Des();
        Q = read();
        for (int i = 1; i <= Q; i++) q[i].l = read(), q[i].r = read() + 1, q[i].id = i;
        sort(q + 1, q + Q + 1);
        l = 1, r = 0;
        for (int i = 1; i <= Q; i++) {
            while (r < q[i].r) Add(pro[++r]);
            while (r > q[i].r) Delet(pro[r--]);
            while (l < q[i].l) Delet(pro[l++]);
            while (l > q[i].l) Add(pro[--l]);
            ans[q[i].id] = now;
        }
        for (int i = 1; i <= Q; i++) cout << ans[i] << '
    ';
    }
    }  // namespace Sub3
    
    namespace Sub1 {
    int cnt[MAXN], a[MAXN];
    struct Query {
        int l, r, id;
        bool operator<(const Query &rhs) const {
            return belong[l] == belong[rhs.l] ? r < rhs.r : belong[l] < belong[rhs.l];
        }
    } q[MAXN];
    void Add(int x, int opt) {
        if (opt) {
            if (x == 0)
                now += r - l + 1;
        } else {
            now += cnt[0];
        }
        cnt[x]++;
    }
    void Delet(int x, int opt) {
        cnt[x]--;
        if (opt) {
            if (x == 0)
                now -= r - l + 1;
        } else {
            now -= cnt[0];
        }
    }
    void solve() {
        block = sqrt(N);
        for (int i = 1; i <= N; i++) belong[i] = (i - 1) / block + 1, a[i] = (s[i] - '0') % 2;
        Q = read();
        for (int i = 1; i <= Q; i++) q[i].l = read(), q[i].r = read(), q[i].id = i;
        sort(q + 1, q + Q + 1);
        l = 1, r = 0;
        for (int i = 1; i <= Q; i++) {
            while (r < q[i].r) Add(a[++r], 1);
            while (r > q[i].r) Delet(a[r--], 1);
            while (l < q[i].l) Delet(a[l++], 0);
            while (l > q[i].l) Add(a[--l], 0);
            ans[q[i].id] = now;
        }
        for (int i = 1; i <= Q; i++) cout << ans[i] << '
    ';
    }
    }
    
    namespace Sub2 {
    int cnt[MAXN], a[MAXN], len[MAXN];
    struct Query {
    	int l, r, id;
    	bool operator < (const Query &rhs) const {
    		return belong[l] == belong[rhs.l] ? r < rhs.r : belong[l] < belong[rhs.l];
    	}
    }q[MAXN];
    void Add(int x, int opt, int pos) {
    	cnt[x]++;
    	if(opt) {
    		if(x == 0 || x == 5) now += r - l + 1;
    	} else {
    		now += cnt[0] + cnt[5];
    	}
    	
    }
    void Delet(int x, int opt, int pos) {
    	if(opt) {
    		if(x == 0 || x == 5) now -= r - l + 1;
    	} else {
    		now -= cnt[0] + cnt[5];
    	}
    	cnt[x]--;
    }
    void solve() { 
    	block = sqrt(N);
    	for(int i = 1; i <= N; i++) belong[i] = (i - 1) / block + 1, a[i] = s[i] - '0';
    	Q = read();
    	for(int i = 1; i <= Q; i++) q[i].l = read(), q[i].r = read(), q[i].id = i;
    	sort(q + 1, q + Q + 1);
    	l = 1, r = 0;
    	for(int i = 1; i <= Q; i++) {	
    		while(l > q[i].l) 
    			--l, Add(a[l], 0, l);
    		while(r > q[i].r) 
    			Delet(a[r], 1, r), r--;
    		while(l < q[i].l) 
    			Delet(a[l], 0, l), l++;
    		while(r < q[i].r) 
    			++r, Add(a[r], 1, r);
    		ans[q[i].id] = now;
    	}
    	for(int i = 1; i <= Q; i++) cout << ans[i] << '
    ';
    }
    
    }
    
    int main() {
        mod = read();
        scanf("%s", s + 1);
        N = strlen(s + 1);
        if (mod == 2)
            Sub1::solve();
        else if (mod == 5)
            Sub2::solve();
        else
            Sub3::solve();
        return 0;
    }
    /*
    11
    1211
    1
    1 4
    */
    
  • 相关阅读:
    搭建本地源
    shell中tar加密打包
    mysql出现ERROR 1819 (HY000)的解决方法
    mysql 创建用户及授权(2)
    mysql 创建用户及授权(1)
    Redis 工具 redis-port 使用
    mysql中 drop、truncate和delete的区别
    dlerror和dlclose用法
    dlsym用法
    dlopen用法
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/10472520.html
Copyright © 2020-2023  润新知