HDU 3333 Turing Tree(树状数组)

原创 2013年12月03日 13:29:13

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

离线处理的好题目

首先对查询区间进行右端点排序,每次求的时候把下标小于右端点的值插入树状数组

每次插入一个值的时候检查这个数字是否在前面出现,出现过就删除前面的,。保留当前的

反正就是每个元素保留一个,且保留的是最后出现的一个,在计算查询区间的时候就可以直接

查询,最后输出结果即可!(注意 long long)

#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <map>
#include <iostream>
using namespace std;
#define LL long long
const int maxn = 100100;
struct point{
    LL x,y;
    LL num;
    long long ans;
}po[maxn];
LL rec[maxn];
LL tree[maxn];
int n,m;
map<int,LL> ma;
bool cmp(const point &a,const point &b){
    return a.y < b.y;
}
bool cmp1(const point &a,const point &b){
    return a.num < b.num;
}
int lowbit(int x){
    return (-x)&x;
}
int update(int pos,LL num){
    while(pos<=n){
        tree[pos]+=num;
        pos+=lowbit(pos);
    }
    return 0;
}
LL sum(int pos){
    LL ans=0;
    while(pos>0){
        ans+=tree[pos];
        pos-=lowbit(pos);
    }
    return ans;
}
int main(){
    int i,j,k,t;
    scanf("%d",&t);
    while(t--){
        memset(tree,0,sizeof(tree));
        ma.clear();
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        scanf("%lld",&rec[i]);
        scanf("%d",&m);
        for(i=1;i<=m;i++){
            scanf("%I64d%I64d",&po[i].x,&po[i].y);
            if(po[i].x>po[i].y){
                swap(po[i].x,po[i].y);
            }
            po[i].num=i;
        }
        sort(po+1,po+m+1,cmp);
        k=1;
        for(i=1;i<=m;i++){
            while(k<=po[i].y){
                if(ma[rec[k]]==0){
                    update(k,rec[k]);
                }
                else{
                    update(ma[rec[k]],-rec[k]);
                    update(k,rec[k]);
                }
                ma[rec[k]]=k;
                k++;
            }
            po[i].ans=sum(po[i].y)-sum(po[i].x-1);
        }
        sort(po+1,po+1+m,cmp1);
        for(i=1;i<=m;i++){
            printf("%I64d\n",po[i].ans);
        }
    }
    return 0;
}



相关文章推荐

HDU 3333 Turing Tree 树状数组离线

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3333 题意:给定一个长度为n的数组,有一些询问:[l, r]内元素的和(相同元素只加一次)。 思路:之...

专题——线段树和树状数组(HDOJ)09 Turing Tree 【hdu 3333】

读入所有query,按右端点递增排序,hash记录当前值的下标,删去(0,t)中相同且非最后一次出现的元素,计算每个query Best solutions for Problem 3333...

HDU 3333 Turing Tree(树状数组离线处理)

HDU 3333 Turing Tree 题目链接 题意:给定一个数组,每次询问一个区间,求出这个区间不同数字的和 思路:树状数组离线处理,把询问按右端点判序,然后用一个map记录下...

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

给出一组序列,问某个区间内序列的和,跟普通求和不同的是,要求值相同的元素只能算一次。 首先看数据范围,就知道要离散化,不然没法标记某个数是否出现过。 然后要对要查询的区间进行排序,按右端点进行排序...

hdu 3333 Turing Tree(树状数组离线操作)

Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To...

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

#include #include #include using namespace std; #define lowbit(x) ((x)&(-x)) #define maxn 30003 #...

HDU-3333:Turing Tree(莫队算法+线段树或树状数组+map或离散化)

HDU-3333:Turing Tree 莫队算法+线段树或树状数组+map或离散化

HDU 3333 树状数组+离线处理

这道题和HDU3874完全一样。 HDU3874解题报告 当然只是数据加强了而已。 唯一的区别就是每个值是10^9,所以要离散化,直接STL搞之,然后下面处理的过程就和3874完全一样了。 ...

HDU 3333 树状数组离线

G Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practi...

HDU(3333)树状数组+离线

题目大意:给出一列数字,再给出一些询问,求询问的区间中,不重复的数字的总和。 思路:数据量较大,可考虑使用离线化操作,将答案存起来一并输出。先把询问的区间右端按照从小到大排序,否则查询的时候需要多次...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 3333 Turing Tree(树状数组)
举报原因:
原因补充:

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