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 }
  • 相关阅读:
    DJango简单的后台定义登录验证
    简单聊聊HTTP/TCP/IP协议
    简单的线程说明
    设计模式 -- 常用设计模式
    网络知识 -- 第二部
    c#利用脚本,本地执行linux命令
    Json和类之间的转化
    关于地址映射穿透和套接字复用的说明
    多线程调用中的注意事项
    Task多线程的常规用法
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/11454440.html
Copyright © 2011-2022 走看看