SPOJ - DQUERY

题目链接:传送门

题目大意:一个容量 n 的数组, m次询问,每次询问 [x,y]内不同数的个数

题目思路:主席树(注意不是权值线段树而是位置线段树)

         也就是按一般线段树的逻辑来写只是用主席树实现而已

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define fi first
#define se second
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define mcp(x,y) memcpy(x,y,sizeof(y))
using namespace std;
#define gamma 0.5772156649015328606065120
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define N 55005
#define maxn 30010
typedef pair<int,int> PII;
typedef long long LL;
LL read(){
    LL x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();}
    return x*f;
}

int n,m,k,ans,v,a[N],b[N],L,R;
int loc[N],root[N<<1],sz;
map<int,int>M;
struct Node{int l,r,v;}seg[N*25];
void update(int &rot,int rt,int l,int r,int pos){
    seg[++sz]=seg[rot],rot=sz;
    seg[rot].v+=v;
    if(l==r)return;
    int mid=l+r>>1;
    if(pos<=mid)update(seg[rot].l,lson,pos);
    else update(seg[rot].r,rson,pos);
}
int query(int rt,int l,int r,int x,int y,int rot){
    if(x<=l&&r<=y)return seg[rot].v;
    int mid=l+r>>1;
    int temp=0;
    if(x<=mid)temp+=query(lson,x,y,seg[rot].l);
    if(y>mid) temp+=query(rson,x,y,seg[rot].r);
    return temp;
}
int main(){
    int i,j,group,x,y,Case=0;
    n=read();
    for(i=1;i<=n;++i)a[i]=read(),b[i]=a[i];
    sort(b+1,b+n+1);
    int _n=unique(b+1,b+n+1)-b-1;
    for(i=1;i<=_n;++i)M[b[i]]=i;
    for(i=1;i<=n;++i){
        v=1;
        if(!loc[M[a[i]]])update(root[i]=root[i-1],1,1,n,i);
        else{
            int temp;
            v=-1;update(temp=root[i-1],1,1,n,loc[M[a[i]]]);
            v=1;update(root[i]=temp,1,1,n,i);
        }
        loc[M[a[i]]]=i;
    }
    m=read();
    for(i=1;i<=m;++i){
        x=read(),y=read();
        printf("%d\n",query(1,1,n,x,y,root[y]));
    }
    return 0;
}
时间: 2024-12-20 01:08:11

SPOJ - DQUERY的相关文章

SPOJ DQUERY D-query 离线+树状数组

本来是想找个主席树的题目来练一下的,这个题目虽说可以用主席树做,但是用这个方法感觉更加叼炸天 第一次做这种离线方法,所谓离线,就在把所有询问先存贮起来,预处理之后再一个一个操作 像这个题目,每个操作要求区间不同元素的个数,我盲目去查的话,某个元素在之前如果出现了,我把他算在当前区间也不好,算在之前的区间也不好,都会出错. 一个好的方法就是把区间排好序,针对某个区间在树状数组上更新以及查询相应值,这样能准确查出结果,但又不影响之后的查询 具体来说,先把区间按右端点进行排序(我一开始按左端点排,想错

SPOJ DQUERY D-query (在线主席树/ 离线树状数组)

SPOJ DQUERY 题意: 给出一串数,询问[L,R]区间中有多少个不同的数 . 解法: 关键是查询到某个右端点时,使其左边出现过的数都记录在它们出现的最右位置置1,其他位置置0,然后直接统计[L,R]的区间和就行了. 在线和离线都可以做 . 话不多说,上代码 . 在线主席树 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 #inc

SPOJ DQUERY D-query(主席树)

题目 Source http://www.spoj.com/problems/DQUERY/en/ Description Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elem

SPOJ D-query(莫队算法模板)

题目链接:http://www.spoj.com/problems/DQUERY/ 题目大意:给定一个数组,每次询问一个区间内的不同元素的个数 解题思路:直接套莫队的裸体 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int N=3e5+5;//区间范围 7 const int MAX

SPOJ DQUERY D-query(莫队基础题)

题目链接:http://www.spoj.com/problems/DQUERY/ 题目: Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subs

SPOJ - DQUERY 主席树

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32356 Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of dist

SPOJ DQUERY - D-query

DQUERY - D-query Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj. In

D-query SPOJ - DQUERY(莫队)统计不同数的数量

A - D-query Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj. Input L

SPOJ - DQUERY: D-query 离线处理 + 树状数组

题目链接:https://vjudge.net/problem/SPOJ-DQUERY 题意:给定数字序列,求任意区间内的不同数字的个数 解法:用树状数组维护 1 ~ i 的区间内不同数字个数的前缀和,首要解决的问题就是同一区间内相同数字统计时相互影响的问题,解决方法如下:离线存储查询的区间,对查询区间按照左端点排序,这样可以优先处理左边的           元素:然后预处理出每一元素下一跳到相同元素的 nxt[]; 这样随着坐标轴指针 l 的移动,l 左边的元素将不会产生任何影响,因为所产生