zoukankan      html  css  js  c++  java
  • 【35.39%】【hdu 3333】Turing Tree

    Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 4776 Accepted Submission(s): 1690

    Problem Description
    After inventing Turing Tree, 3xian always felt boring when solving problems about intervals, because Turing Tree could easily have the solution. As well, wily 3xian made lots of new problems about intervals. So, today, this sick thing happens again…

    Now given a sequence of N numbers A1, A2, …, AN and a number of Queries(i, j) (1≤i≤j≤N). For each Query(i, j), you are to caculate the sum of distinct values in the subsequence Ai, Ai+1, …, Aj.

    Input
    The first line is an integer T (1 ≤ T ≤ 10), indecating the number of testcases below.
    For each case, the input format will be like this:
    * Line 1: N (1 ≤ N ≤ 30,000).
    * Line 2: N integers A1, A2, …, AN (0 ≤ Ai ≤ 1,000,000,000).
    * Line 3: Q (1 ≤ Q ≤ 100,000), the number of Queries.
    * Next Q lines: each line contains 2 integers i, j representing a Query (1 ≤ i ≤ j ≤ N).

    Output
    For each Query, print the sum of distinct values of the specified subsequence in one line.

    Sample Input
    2
    3
    1 1 4
    2
    1 2
    2 3
    5
    1 1 2 1 3
    3
    1 5
    2 4
    3 5

    Sample Output
    1
    5
    6
    3
    6

    Author
    3xian@GDUT

    Source
    HDOJ Monthly Contest – 2010.03.06
    题解

    求一段区间内的不同元素的和。
    需要离线处理询问。
    先讲询问按照右端点升序排序;
    之后顺序扫描每一个数字,如果这个数字之前出现过(用map判断),那么就更新那个那个数字最后的位置为当前位置。并把之前那个数字去掉。
    这样可以保证我们维护了一段数字全都不相同的序列a[1..当前的位置],这个序列中用0代表重复的数字,然后处理右区间为当前位置的询问即可。
    然后用线段树维护区间和,单点更新,单点上传。很简单。
    之前一道类似的题用的是树状数组,所以这次用的线段树。很久没打线段树了。有点生疏。

    #include <cstdio>
    #include <algorithm>
    #include <map>
    #include <iostream>
    #define lson begin,m,rt<<1
    #define rson m+1,end,rt<<1|1
    #define LL long long
    
    using namespace std;
    
    const int MAXN = 30000 + 100;
    const int MAXQ = 1e5 + 100;
    
    struct abc
    {
        int l, r, id;
    };
    
    int a[MAXN], m, n;
    LL sum[MAXN << 2],ans[MAXQ];
    map <int, int> frequent;
    abc Q[MAXQ];
    
    void input(int &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
    }
    
    void build(int begin, int end,int rt)
    {
        sum[rt] = 0;
        if (begin == end)
            return;
        int m = (begin + end) >> 1;
        build(lson);
        build(rson);
    }
    
    bool cmp(abc a, abc b)
    {
        return a.r < b.r;
    }
    
    void add(int begin, int end,int rt, int pos, int key)
    {
        if (begin == end)
        {
            sum[rt] += key;
            return;
        }
        int m = (begin + end) >> 1;
        if (pos <= m)
            add(lson, pos, key);
        else
            add(rson, pos, key);
        sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    }
    
    LL query(int l, int r, int begin, int end, int rt)
    {
        if (l <= begin && end <= r)
            return sum[rt];
        LL temp1 = 0,temp2 = 0;
        int m = (begin + end) >> 1;
        if (l <= m)
            temp1 += query(l, r, lson);
        if (m < r)
            temp2 += query(l, r, rson);
        return temp1 + temp2;
    }
    
    int main()
    {
        //freopen("F:\rush.txt", "r", stdin);
        int t;
        input(t);
        while (t--)
        {
            frequent.clear();
            input(n);
            build(1, n, 1);
            for (int i = 1; i <= n; i++)
                input(a[i]);
            input(m);
            for (int i = 1; i <= m; i++)
                input(Q[i].l), input(Q[i].r), Q[i].id = i;
            sort(Q + 1, Q + 1 + m, cmp);
            int temp = 1;
            for (int i = 1; i <= n; i++)
            {
                if (frequent[a[i]])
                    add( 1, n,1, frequent[a[i]],-a[i]);
                frequent[a[i]] = i;
                add(1, n, 1, i, a[i]);
                while (temp <= m && Q[temp].r == i)
                {
                    ans[Q[temp].id] = query(Q[temp].l, Q[temp].r, 1, n, 1);
                    temp++;
                }
            }
            for (int i = 1; i <= m; i++)
                printf("%I64d
    ", ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    zabbix自定义监控mysql
    [学习笔记]动态树Link-Cut-Tree
    关于 /etc/zabbix/zabbix_agentd.conf 文件 Hostname 文件的说明
    NOIP2018 游记
    Centos7安装Zabbix3.4
    [学习笔记]动态dp
    Java实现 泊松分酒
    关于使用索引的一些经验
    OI生涯回忆录 2017.9.10~2018.11.11
    覆盖索引小结
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632157.html
Copyright © 2011-2022 走看看