• SPOJ


    题意;

      给一个数列${ a_i}$ 一些询问$(l_i,r_i)$ 问你$[l,r]$有多少个不同元素

    题解:
      其实本质思路和离线化处理询问的线段树/树状数组写法差不多,对区间$[x,r]$来说,所有数字只有$r$前面的最后一次出现才有意义

      于是想到通过记录树的版本来保存情况

      先保存数列,再对于每个数字依次建树,如果这个数字之前出现过,就把前一个树的该点删除,再插入新点,作为新树,否则正常键新树

    #include <bits/stdc++.h>
    #define nd seg[now]
    #define ndp seg[pre]
    #define mid ((s+t)>>1)
    using namespace std;
    const int maxn=1e5+10;
    int casn,n,m,k;
    int num[maxn],rt[maxn],size,pos[maxn];
    struct node{
    	int l,r,sum;
    }seg[maxn*20];
    map<int,int>vis;
    void maketree(int s=1,int t=k,int &now=rt[0]){
    	now=++size;nd={s,t,0};
    	if(s==t) return ;
    	maketree(s,mid,nd.l);maketree(mid+1,t,nd.r);
    }
    void update(int &now,int pre,int pos,int x,int s=1,int t=k){
    	now=++size;
    	nd=ndp,nd.sum+=x;
    	if(s==t)return ;
    	if(pos<=mid)update(nd.l,ndp.l,pos,x,s,mid);
    	else update(nd.r,ndp.r,pos,x,mid+1,t);
    }
    int query(int now,int l,int r,int s=1,int t=k){
    	if(l>t||r<s||l>r) return 0;
    	if(l<=s&&r>=t) {
    		return nd.sum;
    	}
    	return query(nd.l,l,r,s,mid)+query(nd.r,l,r,mid+1,t);
    }
    int main(){
    	scanf("%d",&k);
    	for(int i=1;i<=k;i++){
    		scanf("%d",num+i);
    		pos[i]=num[i];
    	}
    	vis.clear();
    	size=0;
    	maketree();
    	int id=0;
    	for(int i=1;i<=k;i++){
    		if(vis[num[i]]!=0) {
    			update(id,rt[i-1],vis[num[i]],-1);
    			update(rt[i],id,i,1);
    		}else update(rt[i],rt[i-1],i,1);
    		vis[num[i]]=i;
    	}
    	scanf("%d",&m);
    	while(m--){
    		int a,b;
    		scanf("%d%d",&a,&b);
    		printf("%d
    ",query(rt[b],a,k));
    	}
      return 0;
    }
  • 相关阅读:
    165. Compare Version Numbers
    164. Maximum Gap
    3、桶排序
    162. Find Peak Element
    160. Intersection of Two Linked Lists
    155. Min Stack
    154. Find Minimum in Rotated Sorted Array II
    153. Find Minimum in Rotated Sorted Array
    Linux/Unix系统编程手册 第二章:基本概念
    Linux/Unix系统编程手册 第一章:历史和标准
  • 原文地址:https://www.cnblogs.com/nervendnig/p/9201515.html
Copyright © 2020-2023  润新知