现在的位置: 首页 > 综合 > 正文

HDU 3333 Turing Tree(树状数组)

2014年02月04日 ⁄ 综合 ⁄ 共 1279字 ⁄ 字号 评论关闭

题目链接: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;
}

抱歉!评论已关闭.