zoukankan      html  css  js  c++  java
  • 【SPOJ3267】D-query-主席树应用

    测试地址:D-query

    题目大意:给一个长为N的数列,Q次询问,每次询问一个区间[i,j]内有多少个不同的数。

    做法:用主席树解决问题,将数列上的数字逐个插入,对于第i次操作,在第i个位置+1并生成一个新的版本,表示在第i个位置新出现一个数,然而要排除重复数字的干扰,我们就把下一个出现这个数的位置称为next[i],在第i个版本中的第next[i]个位置-1,然后对于每一个询问[i,j],答案就是第j个版本与第i-1个版本相减后区间[1,j]的和。

    Update:这题后来我用莫队算法也做了,题解请看这里

    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int n,q,tot=0,last[1000010]={0},nxt[100010]={0},rt[100010]={0};
    struct segnode
    {
      int lc,rc,sum;
    }seg[3000010];
    
    void buildtree(int &no,int l,int r)
    {
      no=++tot;
      seg[no].lc=seg[no].rc=seg[no].sum=0;
      if (l==r) return;
      int mid=(l+r)>>1;
      buildtree(seg[no].lc,l,mid);
      buildtree(seg[no].rc,mid+1,r);
    }
    
    void modify(int last,int &no,int l,int r,int pos,int val)
    {
      no=++tot;
      seg[no]=seg[last];
      if (l==r)
      {
        seg[no].sum+=val;
    	return;
      }
      int mid=(l+r)>>1;
      if (pos<=mid) modify(seg[last].lc,seg[no].lc,l,mid,pos,val);
      else modify(seg[last].rc,seg[no].rc,mid+1,r,pos,val);
      seg[no].sum=seg[seg[no].lc].sum+seg[seg[no].rc].sum;
    }
    
    int query(int fnt,int lst,int l,int r,int t)
    {
      if (r<=t) return seg[lst].sum-seg[fnt].sum;
      int tot=0,mid=(l+r)>>1;
      tot+=query(seg[fnt].lc,seg[lst].lc,l,mid,t);
      if (t>mid) tot+=query(seg[fnt].rc,seg[lst].rc,mid+1,r,t);
      return tot;
    }
    
    int main()
    {
      scanf("%d",&n);
      buildtree(rt[0],1,n);
      
      for(int i=1,a;i<=n;i++)
      {
        scanf("%d",&a);
    	last[a]=nxt[last[a]]=i;
      }
      
      for(int i=1;i<=n;i++)
      {
        modify(rt[i-1],rt[i],1,n,i,1);
    	if (nxt[i]) modify(rt[i],rt[i],1,n,nxt[i],-1);
      }
      
      scanf("%d",&q);
      for(int i=1,a,b;i<=q;i++)
      {
        scanf("%d%d",&a,&b);
    	printf("%d
    ",query(rt[a-1],rt[b],1,n,b));
      }
      
      return 0;
    }
    


  • 相关阅读:
    细说java中的类
    使用LayUI操作数据表格
    使用LayUI展示数据
    一步一步做搜索(一)
    试图加载格式不正确的程序
    自己实现spring核心功能 三
    SpringMvc请求处理流程与源码探秘
    设计模式之代理模式
    爬虫功能介绍
    爬虫监控帮助文档汇总
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793783.html
Copyright © 2011-2022 走看看