zoukankan      html  css  js  c++  java
  • HDU 3333 Turing Tree (树状数组+离线)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3333

    大意是区间求和,不过求的是所有不同元素的和。因此可以从如何去除不同元素方面入手:

    离线存储所有查询并且按照区间最右端下标从小到大排序,为何要这样做后面会提到。

    建树之后,从左到右遍历元素,标记下标,碰见出现过的(我用的是map),就将之前的那个元素置为0,然后重新标记下标为当前值。如果当前位置是一个查询的右端点则直接计算出结果即可。

    由于区间按照右端点排序后,更靠右的区间要么包含之前被置为0的点要么不包括,但一定包含了那个用来置其为0的元素,也就是说前面的更新不会对后面区间产生影响。

    代码:

     1 #define maxn 120005
     2 long long tree[maxn];
     3 long long a[maxn];
     4 int n;
     5 int q, qi[maxn], qj[maxn], f[maxn];
     6 long long qans[maxn];
     7 map<long long, int> mmap;
     8 
     9 long long sum(int i){
    10     long long ans = 0;
    11     while(i){
    12         ans += tree[i];
    13         i -= (i & -i);
    14     }
    15     return ans;
    16 }    
    17 void add(int i, long long x){
    18     while(i <= n){
    19         tree[i] += x;
    20         i += (i & -i);
    21     }
    22 }
    23 int cmp(int i, int j){
    24     return qj[i] < qj[j];
    25 }
    26 
    27 int main(){
    28     int t;
    29     scanf("%d", &t);
    30     while(t--){
    31         memset(tree, 0, sizeof(tree));
    32         memset(a, 0, sizeof(a));
    33         memset(qi, 0, sizeof(qi));
    34         memset(qj, 0, sizeof(qj));
    35         mmap.clear();
    36         scanf("%d", &n);
    37         for(int i = 1; i <= n; i++){
    38             scanf("%lld", &a[i]);
    39             add(i, a[i]);
    40         }
    41         scanf("%d", &q);
    42         for(int i = 1; i <= q; i++){
    43             scanf("%d %d", &qi[i], &qj[i]);
    44             f[i] = i;
    45         }
    46         sort(f + 1, f + q + 1, cmp);
    47         int fc = 1, qc = f[fc];
    48         for(int i = 1; i <= n; i++){
    49             long long tma = a[i];
    50             if(mmap[tma] == 0) mmap[tma] = i;
    51             else {
    52                 int ind = mmap[tma];
    53                 add(ind, -tma);
    54                 mmap[tma] = i;
    55             }
    56             while(qj[qc] == i){
    57                 long long ans = sum(i) - sum(qi[qc] - 1);
    58                 qans[qc] = ans;
    59                 fc++;
    60                 qc = f[fc];
    61             }
    62         }
    63         for(int i = 1; i <= q; i++){
    64             printf("%lld
    ", qans[i]);
    65         }
    66     }
    67 }
    68 /*
    69 2
    70 3
    71 1 1 4
    72 2
    73 1 2
    74 2 3
    75 5
    76 1 1 2 1 3
    77 3
    78 1 5
    79 2 4
    80 3 5
    81 */

    题目:

    Turing Tree

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


    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
  • 相关阅读:
    POJ 1066 Treasure Hunt (线段相交)
    玲珑杯 第4次 String cut(暴力字符串)
    POJ 2653 Pick-up sticks (线段相交)
    HDU 3535 AreYouBusy (混合背包)
    HDU 1712 ACboy needs your help(分组背包)
    HDU 1074 Doing Homework (状压dp)
    POJ 1635 Subway tree systems (树的最小表示法)
    HDU 汉诺塔系列
    HYSBZ 1500 维修数列(伸展树模板)
    photoshop 快速切图
  • 原文地址:https://www.cnblogs.com/bolderic/p/7150214.html
Copyright © 2011-2022 走看看