zoukankan      html  css  js  c++  java
  • hdu3333 Turing Tree

    题目大意:求一个区间内不重复数字的和,例如1 1 1 3,区间[1,4]的和为4。


    思路:如果采用在线算法,很难在nlogn的时间内处理,所以考虑离线算法。

    首先我们把所有查询区间记录下来,然后按照区间的右值排序,接着从左到右把每一个数更新到线段树中,并记录它出现的位置。

    如果一个数已经出现过,那么我们就把他上次出现的位置的值置为0,并更新它出现的位置。

    因为我们的查询区间是按右值排序的,所以当前区间的左值要么和之前一样要么比之前的要大,因此把过去重复出现的数字置为0不会影响结果。

    当更新到某个区间的右值时,我们就查询一次该区间的答案,并把答案记录到对应的地方。

    最后把区间查询的答案按照输入顺序输出即可。

    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <set>
     6 #include <vector>
     7 #include <queue>
     8 #include <stack>
     9 #include <cmath>
    10 #include <map>
    11 using namespace std;
    12 #define INF 0x73737373
    13 #define EPS 1e-8
    14 #define lson l, m, rt<<1
    15 #define rson m+1, r, rt<<1|1
    16 #define MAXN 55555
    17 __int64 sum[MAXN<<2], A[MAXN], ans[MAXN<<2];
    18 map <__int64, int> hash;
    19 struct Query_Node
    20 {
    21     int l, r, index;
    22     friend bool operator < (Query_Node a, Query_Node b)
    23     {
    24         return a.r < b.r;
    25     }
    26 }q[MAXN<<2];
    27 void push_up(int rt)
    28 {
    29     sum[rt] = sum[rt<<1|1] + sum[rt<<1];
    30 }
    31 void update(int l, int r, int rt, int p, __int64 val)
    32 {
    33     if(l == r)
    34     {
    35         sum[rt] += val;
    36         return;
    37     }
    38     int m = (l + r) >> 1;
    39     if(p <= m) update(lson, p, val);
    40     else update(rson, p, val);
    41     push_up(rt);
    42 }
    43 __int64 query(int l, int r, int rt, int L, int R)
    44 {
    45     if(L <= l && R >= r)
    46         return sum[rt];
    47     int m = (l + r) >> 1;
    48     __int64 ret = 0;
    49     if(L <= m) ret += query(lson, L, R);
    50     if(R > m) ret += query(rson, L, R);
    51     return ret;
    52 }
    53 int main()
    54 {
    55     int t;
    56     scanf("%d", &t);
    57     while(t--)
    58     {
    59         int n, m;
    60         hash.clear();
    61         memset(sum, 0, sizeof(sum));
    62         scanf("%d", &n);
    63         for(int i = 1; i <= n; i++)
    64             scanf("%I64d", &A[i]);
    65         scanf("%d", &m);
    66         for(int i = 0; i < m; i++)
    67         {
    68             scanf("%d%d", &q[i].l, &q[i].r);
    69             q[i].index = i;
    70         }
    71         sort(q, q + m);
    72         int pos = 1;
    73         for(int i = 0; i < m; i++)
    74         {
    75             for(;pos <= n && pos <= q[i].r; pos++)
    76             {
    77                 if(hash[A[pos]]) update(1, n, 1, hash[A[pos]], -A[pos]);
    78                 update(1, n, 1, pos, A[pos]);
    79                 hash[A[pos]] = pos;
    80             }
    81             ans[q[i].index] = query(1, n, 1, q[i].l, q[i].r);
    82         }
    83         for(int i = 0; i < m; i++)
    84             printf("%I64d\n", ans[i]);
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    WebForm——浏览器兼容、旋转、缩放、倾斜、移动
    System.Thread.TImer控件——http://www.360doc.com/content/11/0812/11/1039473_139824496.shtml
    U8API——向U8数据库表导入数据
    Grid++Report——打印功能
    Winform—C#读写config配置文件
    WinForm—控制文本框只能输入整数(包括小数)
    WinForm—串口通讯
    SQL Server 数据库存储过程实例
    SQL Server数据库——数据库的数据导出与数据导入
    FlowPortal-BPM——功能:判断数据库表中字段是否重复并阻止提交或保存
  • 原文地址:https://www.cnblogs.com/deadblue/p/2683199.html
Copyright © 2011-2022 走看看