首页 > 代码库 > 主席树初学 SPOJ3267
主席树初学 SPOJ3267
别的没管,直接上的kuangbin代码,懂是基本懂了,然而主席树博大精深们还要多多学习。
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;const int MAXN = 30010;const int M = MAXN * 100;int n,q,tot;int a[MAXN];int T[M],lson[M],rson[M],c[M];int build(int l,int r){ int root = tot++;// printf ("%d---%d,%d\n",l,r,root); c[root] = 0; if(l != r) { int mid = (l+r)>>1; lson[root] = build(l,mid); rson[root] = build(mid+1,r); } return root;}int update(int root,int pos,int val){ int newroot = tot++;//全新的节点 int tmp = newroot;//记录,说明这个点开始是新的树,即将开始找 c[newroot] = c[root] + val;//这个点的值是上一个节点再加上这个新的值(因为这个值保证全新) int l = 1, r = n;//总区间 while(l < r)//说明还没到最深 { int mid = (l+r)>>1;//左右分界 if(pos <= mid)//在区间左边,说明右边不用动,直接拿来用,指一下 { lson[newroot] = tot++;//左边新开节点记录 rson[newroot] = rson[root];//右边承接上一个 newroot = lson[newroot];//去新的点 root = lson[root];//上一个根跟着深入左边 r = mid;//右边不用管了(确定层数) } else//左边是还没有更新的节点,但是仍然要指,不然会漏,主要用于删除 { rson[newroot] = tot++; lson[newroot] = lson[root]; newroot = rson[newroot]; root = rson[root]; l = mid+1; } c[newroot] = c[root] + val;//新的点都要加(因为深入的地方总是带着这个新点) } return tmp;//返回节点}int query(int root,int pos){ int ret = 0; int l = 1, r = n; while(pos < r) { int mid = (l+r)>>1; if(pos <= mid)//在左边,说明这个点不足,只有深入 { r = mid;//右边舍去 root = lson[root];//根去左边 } else { ret += c[lson[root]];//在右边,说明左边的这个子区间可以全加上 root = rson[root]; l = mid+1; } } return ret + c[root];//最后一个左区间}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(scanf("%d",&n) == 1) { tot = 0; for(int i = 1; i <= n; i++) scanf("%d",&a[i]); T[n+1] = build(1,n); map<int,int>mp; for(int i = n; i>= 1; i--) //T[i]中是对每一个数(位置)的根 { if(mp.find(a[i]) == mp.end()) { T[i] = update(T[i+1],i,1);// printf ("1---%d---%d\n",a[i],T[i+1]); } else { int tmp = update(T[i+1],mp[a[i]],-1);//为了清除之前的状态,但是不得记录,就当是瞎了 T[i] = update(tmp,i,1); } mp[a[i]] = i; } scanf("%d",&q); while(q--) { int l,r; scanf("%d%d",&l,&r); printf("%d\n",query(T[l],r));//在l这棵树中找r } } return 0;}
主席树初学 SPOJ3267
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。