HDU 3333 Turing Tree 线段树 or 树状数组

原创 2012年03月22日 20:15:02

给出一组序列,问某个区间内序列的和,跟普通求和不同的是,要求值相同的元素只能算一次。

首先看数据范围,就知道要离散化,不然没法标记某个数是否出现过。

然后要对要查询的区间进行排序,按右端点进行排序。

然后按顺序遍历点,如果该点的值以前出现过,就删掉以前的那个,然后插入该点,记录下这个值的位置。刚才已经对询问区间排序了,那么所有右端点在该点的区间都可以进行查询了。

那么为什么要这么干呢。观察一个区间,我们可以发现,如果出现重复的,尽量删除左边的,保留右边的,那么右端点相同的区间都可以进行查询。

下面是树状数组版本的,不得不说树状数组求区间和实在是比较方便


/*
ID: sdj22251
PROG: subset
LANG: C++
*/
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#define MAXN 66666
#define MAXM 104444
#define INF 100000000
#define eps 1e-7
#define L(X) X<<1
#define R(X) X<<1|1
using namespace std;
struct interval
{
    int l, r, id;
    bool operator <(const interval &a)const
    {
        return r < a.r;
    }
}p[MAXM];
int x[MAXN], a[MAXN], h[MAXN], n;
long long tx[MAXN], ans[MAXM];
int bin(int v, int bound)
{
    int low = 0, high = bound - 1;
    while(low <= high)
    {
        int mid = (low + high) >> 1;
        if(x[mid] == v) return mid;
        if(x[mid] < v) low = mid + 1;
        else high = mid - 1;
    }
    return -1;
}
int lowbit(int x)
{
    return x & -x;
}
void modify(int x, int v)
{
    for(int i = x; i <= n; i += lowbit(i))
        tx[i] += v;
}
long long get_sum(int x)
{
    long long sum = 0;
    for(int i = x; i > 0; i -= lowbit(i))
    sum += tx[i];
    return sum;
}
int main()
{
    int T, m;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        int cnt = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            x[cnt++] = a[i];
        }
        memset(tx, 0, sizeof(tx));
        sort(x, x + cnt);
        cnt = unique(x, x + cnt) - x;
        scanf("%d", &m);
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d", &p[i].l, &p[i].r);
            p[i].id = i;
        }
        sort(p, p + m);
        for(int i = 0; i < cnt; i++)
            h[i] = 0;
        int j = 0;
        for(int i = 1; i <= n; i++)
        {
            int id = bin(a[i], cnt);
            if(h[id]) modify(h[id], -a[i]);
            modify(i, a[i]);
            h[id] = i;
            for(; j < m; j++)
            {
                if(p[j].r == i) ans[p[j].id] = get_sum(p[j].r) - get_sum(p[j].l - 1);
                else break;
            }
        }
        for(int i = 0; i < m; i++)
        printf("%I64d\n", ans[i]);
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu 3333 Turing Tree 线段树/树状数组

题意:求给定去接内不重复数字的和 做法: 图灵树还是没有学到.... 只要先记录每个询问,然后按照右边界排序,还需要记录每个位置之前距离它最近那个与他相等的元素的位置。再树状数组做一下。 #in...
  • cqlf__
  • cqlf__
  • 2013年04月28日 19:58
  • 684

HDU - 3333 Turing Tree(树状数组)

题目大意:给出N个数,M个询问,询问的是[a,b]区间内所有不相同的数的和解题思路:现在的问题是,怎么处理那些相同的数 我们可以一个个的修改树状数组,边修改,边求值,如果修改的位置刚好是询问的右边界...
  • L123012013048
  • L123012013048
  • 2015年10月20日 16:04
  • 252

hdu 3333 Turing Tree 树状数组或者线段树

#include #include #include using namespace std; #define lowbit(x) ((x)&(-x)) #define maxn 30003 #...
  • a601025382s
  • a601025382s
  • 2013年07月20日 12:58
  • 557

HDU 3333 Turing Tree(树状数组 || 线段树)

题意:给定一个区间,q个查询,对于每次查询回答这个区间内所有不重复的数的和。 思路:可以考虑使用树状数组来做。 先读入所有查询,离线来做,将所有查询按右端点升序排序。 那么我们从给定区间的第一个...
  • u014664226
  • u014664226
  • 2015年08月06日 01:19
  • 622

hdu 3333 Turing Tree 树状数组

这道题和 hdu 3874 几乎一模一样 #include #include #include #include using namespace std; typedef long...
  • zhoutonglx
  • zhoutonglx
  • 2015年07月17日 18:45
  • 181

HDU 3333 Turing Tree(离线操作+线段树||树状数组)

After inventing Turing Tree, 3xian always felt boring when solving problems about intervals, because...
  • qq_37497322
  • qq_37497322
  • 2017年07月27日 09:45
  • 211

HDU 3333 Turing Tree(树状数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3333 离线处理的好题目 首先对查询区间进行右端点排序,每次求的时候把下标小于右端点的值插入树状数组...
  • sunrainchy
  • sunrainchy
  • 2013年12月03日 13:29
  • 447

hdu 3333 Turing Tree ( 树状数组)

使用数组数组,一边插入
  • u013781361
  • u013781361
  • 2014年04月09日 12:44
  • 347

HDU 3333 Turing Tree(线段树)

Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To...
  • Shili_Xu
  • Shili_Xu
  • 2017年09月24日 18:27
  • 73

hdu 3333 Turing Tree 线段树

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3333 题意:给出n个数的一个序列,询问m次,每次询问区间[i,j]内改序列不同数之和,就是说该区间如果某...
  • fallenfall
  • fallenfall
  • 2013年10月20日 16:39
  • 510
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 3333 Turing Tree 线段树 or 树状数组
举报原因:
原因补充:

(最多只允许输入30个字)