• SPOJ


    题目链接:https://vjudge.net/problem/SPOJ-DQUERY

    题目大意:给定一个含有n个数的序列,有q个询问,每次询问区间[l,r]中不同数的个数。

    解题思路:从左向右一个一个将该数字处在的位置添加到主席树中

    如果该数字前面未出现过,则在此版本的线段树中的该条链加1,如果该数字已经出现过了,则在此版本线段树的上次出现位置减1,再在此版本线段树的该位置加1,这样就能保证区间不重复计算。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=30005;
    struct node{
        int l,r,sum;
    }T[maxn*40];
    int n,q,a[maxn],cnt,root[maxn],pos[1000005];
    void update(int &now,int pre,int val,int l,int r,int pos){
        T[++cnt]=T[pre],T[cnt].sum+=val,now=cnt;
        if(l==r) return;
        int mid=l+r>>1;
        if(pos<=mid) update(T[now].l,T[pre].l,val,l,mid,pos);
        else update(T[now].r,T[pre].r,val,mid+1,r,pos);
    }
    int query(int L,int R,int l,int r,int rt){
        if(L<=l&&R>=r) return T[rt].sum;
        int ans=0,mid=l+r>>1;
        if(L<=mid) ans+=query(L,R,l,mid,T[rt].l);
        if(R>mid) ans+=query(L,R,mid+1,r,T[rt].r);
        return ans;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++){
            if(pos[a[i]]){
                update(root[i],root[i-1],-1,1,n,pos[a[i]]);
                update(root[i],root[i],1,1,n,i);
            }else update(root[i],root[i-1],1,1,n,i);
            pos[a[i]]=i;
        } 
        scanf("%d",&q);
        while(q--){
            int l,r;
            scanf("%d%d",&l,&r);
            printf("%d
    ",query(l,r,1,n,root[r]));
        }
        return 0;
    }
  • 相关阅读:
    专题实验 Toad 用户的创建与管理( 包括 role 等 )
    专题实验 字符集(全球化支持)
    Toad 所有 菜单说明(太多)
    java 调试
    java 基础数据结构
    HeadFirst Jsp 09 (JSTL)
    HeadFirst jsp 08 无脚本JSP
    14 多线程
    Struts2配置
    Struts框架搭建时所遇到的问题
  • 原文地址:https://www.cnblogs.com/zjl192628928/p/11257876.html
Copyright © 2020-2023  润新知