zoukankan      html  css  js  c++  java
  • HDU 3874 Necklace (数状数组)

    题意:求[l, r]区间内不重复的数的和。N个数,M次询问

    解:离线处理M次询问,看得别人的思路后才知道的。。。思维局限在预处理N个数上了。。。

    对M次询问按右区间的值从小到大排序。扫一遍N个数,如果发现当前这个数在之前出现过,就从之前出现这个数的位置上把这个数删除,在新位置上插入这个数。这样做的好处是删除前面重复的不会影响后面的。时间复杂度控制在(N + M)logN的数量级上。

    ps:午不眠,困乎,我命休矣。

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    #include <stack>
    #include <map>
    #include <queue>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%I64d\n", x)
    #define Read()  freopen("data.in", "r", stdin)
    #define Write() freopen("data.out", "w", stdout);
    
    typedef __int64 LL;
    const double eps = 1e-6;
    const double PI = acos(-1.0);
    const int inf = 0x1F1F1F1F;
    
    using namespace std;
    
    const int N = 50010;
    const int M = 200010;
    
    struct node {
        int l, r;
        int id;
        bool operator < (const node& cmp) const {
            return r < cmp.r;
        }
    }p[M];
    
    LL c[N];
    LL ans[M];
    int num[N];
    map<int, int> mp;
    
    int lowbit(int i) {
        return i&(-i);
    }
    
    void add(int p, int val) {
        for( ; p < N; p += lowbit(p)) {
            c[p] += val;
        }
    }
    
    LL sum(int p) {
        LL res = 0;
        for( ; p > 0; p -= lowbit(p)) {
            res += c[p];
        }
        return res;
    }
    
    int main() {
        //Read();
    
        int T, n, m, i, r, t;
        scanf("%d", &T);
        while(T--) {
            scanf("%d", &n);
            for(i = 1; i <= n; ++i) scanf("%d", num + i);
            scanf("%d", &m);
            for(i = 0; i < m; ++i) {
                scanf("%d%d", &p[i].l, &p[i].r);
                if(p[i].l > p[i].r) swap(p[i].l, p[i].r);
                p[i].id = i;
            }
            sort(p, p + m);
            memset(c, 0, sizeof(c));
            mp.clear();
            r = 1;
            for(i = 0; i < m; ++i) {
                while(r <= p[i].r) {
                    t = num[r];
                    if(mp[t] != 0) {
                        add(mp[t], -t);
                    }
                    add(r, t);
                    mp[t] = r++;
                }
                ans[p[i].id] = sum(p[i].r) - sum(p[i].l - 1);
            }
            for(i = 0; i < m; ++i) {
                OUT(ans[i]);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    get与post的区别
    细数28个服务器端控件
    学习笔记
    是Attribute,还是Property
    学习日记
    C#常见面视题(附答案)
    扩展GridView(八)——导出为Excel
    如何实现ObjectDataSource与GridView的分页操作
    asp.net程序性能优化总结
    Array和ArrayList的异同点
  • 原文地址:https://www.cnblogs.com/vongang/p/3118811.html
Copyright © 2011-2022 走看看