zoukankan      html  css  js  c++  java
  • luogu SP3267 DQUERY

    传送:https://www.luogu.org/jump/spoj/3267

    题意:

    给定一个长度为$n$的序列,$q$个询问,问区间$[l,r]$内的不同数的个数。

    数据范围:

    $1<=n<=30000,1<=a_i<=10^6,1<=q<=200000$。

    分析:

    求区间内不同数的个数。很明显是莫队的裸题。

    那么对于主席树怎么做呢?

    统计不同数的个数,那么就是看一个数是否在同一区间内出现多次。

    那么就可以记录一个数字后一个出现的位置,即第$i$个位置的数字后一个出现的位置为$nxt[i]$。

    统计答案的时候就是可以求区间$[l,r]$内的$nxt[i]$是否有$<=r$的,这样就代表有重复。

    换一句话就是求区间$[l,r]$内,$nxt[i]$在$[r+1,n+1]$范围内的个数。

    那么主席树维护数组下标,每个主席树是权值线段树,代表后一个位置出现数字的个数。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=3e4+10;
     4 struct node{
     5     int l,r,num;
     6 }tree[maxn*100];
     7 int size=0,root[maxn],a[maxn],nxt[maxn];
     8 map<int,int> mp;
     9 void update(int &x,int y,int l,int r,int dex){
    10     x=++size; tree[x]=tree[y]; tree[x].num++;
    11     if(l==r) return ;
    12     int mid=(l+r)>>1;
    13     if (dex<=mid) update(tree[x].l,tree[y].l,l,mid,dex);
    14     else update(tree[x].r,tree[y].r,mid+1,r,dex); 
    15 }
    16 int query(int x,int y,int l,int r,int xx,int yy){
    17     if (xx<=l && r<=yy) return tree[y].num-tree[x].num;
    18     int mid=(l+r)>>1;
    19     int res=0;
    20     if (xx<=mid) res+=query(tree[x].l,tree[y].l,l,mid,xx,yy);
    21     if (yy>mid) res+=query(tree[x].r,tree[y].r,mid+1,r,xx,yy);
    22     return res;
    23 }
    24 int main(){
    25     int n;scanf("%d",&n);
    26     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    27     mp.clear();
    28     for (int i=n;i>=1;i--){
    29         if (mp[a[i]]==0) nxt[i]=n+1;
    30         else nxt[i]=mp[a[i]];
    31         mp[a[i]]=i;
    32     } 
    33     for (int i=1;i<=n;i++){
    34         update(root[i],root[i-1],1,n+1,nxt[i]);
    35     }
    36     int m,x,y;scanf("%d",&m);
    37     while(m--){
    38         scanf("%d%d",&x,&y);
    39         int ans=query(root[x-1],root[y],1,n+1,y+1,n+1);
    40         printf("%d
    ",ans);
    41     }
    42     return 0;
    43 }
  • 相关阅读:
    day06_02 继承
    day06_03 多继承区别
    day03_04 字符集编码转换
    day04_03 序列化与反序列化
    day04_06 单线程生成器的并行效果(协程)
    day04_02 装饰器 高阶版
    day04_05 内置方法
    复合控件的开发心得
    从子节点找父节点的循环sql
    asp中试用存储过程
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/11454440.html
Copyright © 2011-2022 走看看