zoukankan      html  css  js  c++  java
  • HDU 3333 Turing Tree 莫队算法

    题意:

    给出一个序列和若干次询问,每次询问一个子序列去重后的所有元素之和。

    分析:

    先将序列离散化,然后离线处理所有询问。
    用莫队算法维护每个数出现的次数,就可以一边移动区间一边维护不同元素之和。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    typedef long long LL;
    
    const int maxn = 30000 + 10;
    const int maxq = 100000 + 10;
    
    int n, m, a[maxn], b[maxn];
    int cnt[maxn];
    LL ans[maxq];
    
    struct Query
    {
        int l, r, id;
        bool operator < (const Query& t) const {
            return ((l / m) < (t.l / m)) || ((l / m) == (t.l / m) && r < t.r);
        }
    };
    
    Query q[maxq];
    
    int main()
    {
        int T; scanf("%d", &T);
        while(T--) {
            scanf("%d", &n);
            for(int i = 1; i <= n; i++) { scanf("%d", a + i); b[i] = a[i]; }
            sort(b + 1, b + 1 + n);
            int tot = unique(b + 1, b + 1 + n) - b - 1;
            for(int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + 1 + tot, a[i]) - b;
    
            m = sqrt(n);
            int Q; scanf("%d", &Q);
            for(int i = 1; i <= Q; i++) {
                scanf("%d%d", &q[i].l, &q[i].r);
                q[i].id = i;
            }
            sort(q + 1, q + 1 + Q);
    
            LL sum = 0;
            int L = 1, R = 0;
            memset(cnt, 0, sizeof(cnt));
            for(int i = 1; i <= Q; i++) {
                while(L < q[i].l) {
                    cnt[a[L]]--;
                    if(!cnt[a[L]]) sum -= b[a[L]];
                    L++;
                }
                while(L > q[i].l) {
                    L--;
                    if(!cnt[a[L]]) sum += b[a[L]];
                    cnt[a[L]]++;
                }
                while(R < q[i].r) {
                    R++;
                    if(!cnt[a[R]]) sum += b[a[R]];
                    cnt[a[R]]++;
                }
                while(R > q[i].r) {
                    cnt[a[R]]--;
                    if(!cnt[a[R]]) sum -= b[a[R]];
                    R--;
                }
                ans[q[i].id] = sum;
            }
    
            for(int i = 1; i <= Q; i++) printf("%lld
    ", ans[i]);
        }
    
        return 0;
    }
    
    
  • 相关阅读:
    Stream流之三级查询
    SpringBoot日期格式的设置
    el表达式
    SpringMV+HuTool之验证码登录
    Spring注解详解
    @ResponseBody注解使用(返回字符串并不跳转)
    每日leetcode-数组-589. N 叉树的前序遍历
    python apply函数
    剑指offer-JZ6 旋转数组的最小数字
    torch.manual_seed()函数
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/5474556.html
Copyright © 2011-2022 走看看