码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3333 Turing Tree (离线询问+线段树)

时间:2015-05-06 17:42:00      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:acm   算法与数据结构   编程   线段树   

题目地址:HDU 3333
将询问离线保存下来,然后将数组的点离散化,记录每个值上一次出现的位置。然后枚举数组的数,若当前枚举的数前面出现过,那么就删掉前面出现过的那个位置上的数,更新当前这个位置上的数,然后那些所有询问的右端点为当前位置的就可以通过查询来得到结果了。
更新与查询用线段树来优化。
代码如下:

#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
using namespace std;
#define LL long long
#define pi acos(-1.0)
#pragma comment(linker, "/STACK:1024000000,1024000000")
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const double eqs=1e-3;
const int MAXN=30000+10;
#define root 0, n-1, 1
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
struct node
{
        int l, r, id;
        LL ans;
}qu[MAXN<<2];
int a[MAXN], c[MAXN], b[MAXN], pos[MAXN], cnt;
LL sum[MAXN<<2];
int BS(int x)
{
        int low=0, high=cnt-1, mid;
        while(low<=high){
                mid=low+high>>1;
                if(c[mid]==x) return mid;
                else if(c[mid]>x) high=mid-1;
                else low=mid+1;
        }
}
bool cmp(node f1, node f2)
{
        return f1.r<f2.r;
}
bool cmp1(node f1, node f2)
{
        return f1.id<f2.id;
}
void PushUp(int rt)
{
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void Update(int p, int x, int l, int r, int rt)
{
        if(l==r){
                sum[rt]=(LL)x;
                return ;
        }
        int mid=l+r>>1;
        if(p<=mid) Update(p,x,lson);
        else Update(p,x,rson);
        PushUp(rt);
}
LL Query(int ll, int rr, int l, int r, int rt)
{
        if(ll<=l&&rr>=r){
                return sum[rt];
        }
        int mid=l+r>>1;
        LL ans=0;
        if(ll<=mid) ans+=Query(ll,rr,lson);
        if(rr>mid) ans+=Query(ll,rr,rson);
        return ans;
}
int main()
{
        int q, i, T, n, x, j;
        scanf("%d",&T);
        while(T--){
                scanf("%d",&n);
                for(i=0;i<n;i++){
                        scanf("%d",&a[i]);
                        b[i]=a[i];
                }
                sort(b,b+n);
                c[0]=b[0];
                cnt=1;
                for(i=1;i<n;i++){
                        if(b[i]!=b[i-1]){
                                c[cnt++]=b[i];
                        }
                }
                scanf("%d",&q);
                for(i=0;i<q;i++){
                        scanf("%d%d",&qu[i].l,&qu[i].r);
                        qu[i].id=i;
                }
                sort(qu,qu+q,cmp);
                memset(pos,-1,sizeof(pos));
                j=0;
                for(i=0;i<n;i++){
                        x=BS(a[i]);
                        if(pos[x]!=-1){
                                Update(pos[x],0,root);
                        }
                        Update(i,a[i],root);
                        pos[x]=i;
                        while(qu[j].r==i+1){
                                qu[j].ans=Query(qu[j].l-1,qu[j].r-1,root);
                                j++;
                        }
                }
                sort(qu,qu+q,cmp1);
                for(i=0;i<q;i++){
                        printf("%lld\n",qu[i].ans);
                }
        }
        return 0;
}

HDU 3333 Turing Tree (离线询问+线段树)

标签:acm   算法与数据结构   编程   线段树   

原文地址:http://blog.csdn.net/scf0920/article/details/45538049

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!