主席树学习记录
来源:互联网 发布:app软件官方下载 编辑:程序博客网 时间:2024/04/29 14:55
搞了一段时间网络流后,最后还是回到了数据结构。。。
主席树,引fotile主席的一段话:
..这个东西是当初我弱不会划分树的时候写出来替代的一个玩意..被一小撮别有用心的人取了很奇怪的名字> <
想法是对原序列的每一个前缀[1..i]建立出一颗线段树维护值域上每个数的出现次数,然后发现这样的树是可以减的,然后就没有然后了
其实是一种比较好理解的数据结构(至少静态查找时是如此),我们对于每个点,建一个类似与前缀和的线段树,然后我们发现这样的n棵线段树是可以相减的,于是。。。但是在实现过程中,由于内存限制的原因,我们一般用指针实现。
COGS 930 找第k小的数。裸题,直接上模板。code:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define mid (l+r)/2using namespace std;struct node{node *left,*right;int a,size;node(){left=right=NULL; size=a=0;}int updata() { size=a; if (left) size+=left->size; if (right) size+=right->size; }}*null=new node(),*root[100001]={NULL},q[2000001];int n,m,a[100001],b[100001];int temp,ans;void build(node *&y,node *&x,int l,int r,int t){if (x==NULL) x=null;y=&q[++temp]; *y=node();if (l==r) { *y=*x; y->size++; y->a++;return; }if (t<=b[mid]) { build(y->left,x->left,l,mid,t); y->right=x->right; y->updata(); }else { build(y->right,x->right,mid+1,r,t); y->left=x->left; y->updata(); }}void find(node *x1,node *x2,int l,int r,int k){int ls;if (x1==NULL) x1=null; if (x2==NULL) x2=null;ls=0;if (l==r) {ans=b[l]; return;}if (x2->left) ls+=x2->left->size;if (x1->left) ls-=x1->left->size;if (ls>=k) find(x1->left,x2->left,l,mid,k);else find(x1->right,x2->right,mid+1,r,k-ls);}int main(){int i,size,x,l,r,k;freopen("kth.in","r",stdin);freopen("kth.out","w",stdout);scanf("%d%d",&n,&m);null->left=null; null->right=null;for (i=1;i<=n;++i) { scanf("%d",&a[i]); b[i]=a[i]; }sort(b+1,b+n+1);size=unique(b+1,b+n+1)-b-1;temp=0;for (i=1;i<=n;++i) build(root[i],root[i-1],1,size,a[i]);for (i=1;i<=m;++i) { scanf("%d%d%d",&l,&r,&k); ans=0; find(root[l-1],root[r],1,size,k); printf("%d\n",ans); }fclose(stdin);fclose(stdout);}
动态主席树,其实救是树状数组套线段树,COGS 257 动态排名系统 code:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define mid (l+r)/2using namespace std;struct hp{int size,l,r;}tree[10000001];struct hq{char op;int x,y,k;}qst[10001];int t,n,m,tot,size;int root[50001],a[50001],b[60001],q1[2000],q2[2000];int lowbit(int x) {return x&(-x); }void build(int &x,int l,int r){tree[x=++tot].size=0;if (l==r) return;build(tree[x].l,l,mid); build(tree[x].r,mid+1,r);}void insert(int last,int &i,int l,int r,int x,int flag){tree[i=++tot].size=tree[last].size+flag;tree[i].l=tree[last].l; tree[i].r=tree[last].r;if (l==r) return;if (x<=mid) insert(tree[last].l,tree[i].l,l,mid,x,flag);else insert(tree[last].r,tree[i].r,mid+1,r,x,flag);}void bit_ins(int i,int x,int flag){for (;i<=n;i+=lowbit(i)) insert(root[i],root[i],1,size,x,flag);}int ask(int l,int r,int k){int ss=0,i;if (l==r) return l;for (i=1;i<=q2[0];++i) ss+=tree[tree[q2[i]].l].size;for (i=1;i<=q1[0];++i) ss-=tree[tree[q1[i]].l].size;if (k<=ss) { for (i=1;i<=q2[0];++i) q2[i]=tree[q2[i]].l; for (i=1;i<=q1[0];++i) q1[i]=tree[q1[i]].l; return ask(l,mid,k); }else { for (i=1;i<=q2[0];++i) q2[i]=tree[q2[i]].r; for (i=1;i<=q1[0];++i) q1[i]=tree[q1[i]].r; return ask(mid+1,r,k-ss); }}int bit_ask(int l,int r,int k){q2[0]=q1[0]=0;for (;r;r-=lowbit(r)) q2[++q2[0]]=root[r];for (;l;l-=lowbit(l)) q1[++q1[0]]=root[l];return ask(1,size,k);}int main(){int i,j;freopen("dynrank.in","r",stdin);freopen("dynrank.out","w",stdout);scanf("%d",&t);while (t) { memset(root,0,sizeof(root)); memset(tree,0,sizeof(tree)); tot=0; b[0]=0; scanf("%d%d",&n,&m); for (i=1;i<=n;++i) { scanf("%d",&a[i]); b[0]++;b[b[0]]=a[i]; } for (i=1;i<=m;++i) { scanf("%*c%c",&qst[i].op); if (qst[i].op=='Q') scanf("%d%d%d",&qst[i].x,&qst[i].y,&qst[i].k); else { scanf("%d%d",&qst[i].x,&qst[i].k); b[0]++; b[b[0]]=qst[i].k; } } sort(b+1,b+b[0]+1); size=unique(b+1,b+b[0]+1)-b-1; build(root[0],1,size); for (i=1;i<=n;++i) { a[i]=upper_bound(b+1,b+size+1,a[i])-b-1; bit_ins(i,a[i],1); } for (i=1;i<=m;++i) { if (qst[i].op=='Q') { j=bit_ask(qst[i].x-1,qst[i].y,qst[i].k); printf("%d\n",b[j]); } else { bit_ins(qst[i].x,a[qst[i].x],-1); a[qst[i].x]=upper_bound(b+1,b+size+1,qst[i].k)-b-1; bit_ins(qst[i].x,a[qst[i].x],1); } } t--; }fclose(stdin);fclose(stdout);}
其实稍微转化一下就成模板题啦~~ code:
#include<iostream>#include<cstdio>#include<cstring>#define mid (l+r)/2using namespace std;struct hp{int size,l,r;}tree[10000000];int root[100001],q1[2000],q2[2000],n,m;int a[100001],a2[100001],c[100001],pos[100001],tot,del[100001];long long ansi[50001]={0};int lowbit(int x) { return x&(-x); }long long work(int l,int r){int i,j;int ans=0;if (l==r) return ans;ans+=work(l,mid)+work(mid+1,r);i=l; j=mid+1; c[0]=0;while (i<=mid&&j<=r) { if (a2[i]<a2[j]) { c[++c[0]]=a2[i]; i++; } else { c[++c[0]]=a2[j]; j++; ans+=mid-i+1; } }for (;i<=mid;++i) c[++c[0]]=a2[i];for (;j<=r;++j) c[++c[0]]=a2[j];for (i=l;i<=r;++i) a2[i]=c[i-l+1];return ans;}void build(int &x,int l,int r){tree[x=++tot].size=0;if (l==r) return;build(tree[x].l,l,mid); build(tree[x].r,mid+1,r);}long long askless(int l,int r,int x){int ss=0;int i;if (l==r) return 0;for (i=1;i<=q2[0];++i) ss+=tree[tree[q2[i]].l].size;for (i=1;i<=q1[0];++i) ss-=tree[tree[q1[i]].l].size;if (x<=mid) { for (i=1;i<=q2[0];++i) q2[i]=tree[q2[i]].l; for (i=1;i<=q1[0];++i) q1[i]=tree[q1[i]].l; return askless(l,mid,x); }else { for (i=1;i<=q2[0];++i) q2[i]=tree[q2[i]].r; for (i=1;i<=q1[0];++i) q1[i]=tree[q1[i]].r; return ss+askless(mid+1,r,x); }}long long askmore(int l,int r,int x){int ss=0;int i;if (l==r) return 0;for (i=1;i<=q2[0];++i) ss+=tree[tree[q2[i]].r].size;for (i=1;i<=q1[0];++i) ss-=tree[tree[q1[i]].r].size;if (x>mid) { for (i=1;i<=q2[0];++i) q2[i]=tree[q2[i]].r; for (i=1;i<=q1[0];++i) q1[i]=tree[q1[i]].r; return askmore(mid+1,r,x); }else { for (i=1;i<=q2[0];++i) q2[i]=tree[q2[i]].l; for (i=1;i<=q1[0];++i) q1[i]=tree[q1[i]].l; return ss+askmore(l,mid,x); }}long long bit_askless(int l,int r,int x){q1[0]=q2[0]=0;for (;l;l-=lowbit(l)) q1[++q1[0]]=root[l];for (;r;r-=lowbit(r)) q2[++q2[0]]=root[r];askless(1,n,x);}long long bit_askmore(int l,int r,int x){q1[0]=q2[0]=0;for (;l;l-=lowbit(l)) q1[++q1[0]]=root[l];for (;r;r-=lowbit(r)) q2[++q2[0]]=root[r];askmore(1,n,x);}void insert(int last,int &i,int l,int r,int x,int flag){if (!i) i=++tot;tree[i].size=tree[last].size+flag;tree[i].l=tree[last].l; tree[i].r=tree[last].r;if (l==r) return; if (x<=mid) insert(tree[last].l,tree[i].l,l,mid,x,flag);else insert(tree[last].r,tree[i].r,mid+1,r,x,flag);}void bit_ins(int i,int x,int flag){for (;i<=n;i+=lowbit(i)) insert(root[i],root[i],1,n,x,flag);}int main(){int i; long long ans=0;scanf("%d%d",&n,&m); tot=0;for (i=1;i<=n;++i) { scanf("%d",&a[i]); pos[a[i]]=i; } for (i=1;i<=m;++i) { scanf("%d",&del[i]); a[pos[del[i]]]=0; } build(root[0],1,n); for (i=1;i<=n;++i) if (a[i]) { bit_ins(i,a[i],1); a2[++a2[0]]=a[i]; } ans=work(1,a2[0]); for (i=m;i>=1;--i) { bit_ins(pos[del[i]],del[i],1); if (pos[del[i]]>1) ans+=bit_askmore(0,pos[del[i]]-1,del[i]); if (pos[del[i]]<n) ans+=bit_askless(pos[del[i]],n,del[i]); ansi[i]=ans; } for (i=1;i<=m;++i) printf("%lld\n",ansi[i]);}
0 0
- 主席树学习记录
- 学习记录5:主席树
- 主席树学习笔记
- 主席树学习
- 主席树学习笔记
- 主席树学习小结
- 主席树学习笔记
- 主席树学习
- 主席树学习笔记
- 主席树学习--入门
- 主席树 学习整理
- 学习总结:主席树
- 主席树学习笔记
- 主席树入门学习
- 主席树模版 记录历史操作
- 主席树学习笔记(poj2104)
- 主席、树、主席树!
- 【BZOJ2809】【codevs1763】派遣,主席树记录前缀和
- hdu 1063 Exponentiation
- oc编程中一种错误
- d3的一些东西
- 2012 PHP热门资料64个+经典源码50个——下载目录 :
- 最短路径A*算法原理及java代码实现(看不懂是我的失败)
- 主席树学习记录
- Linux的运行级别和chkconfig用法
- SQL Server将一列的多行内容拼接成一行或一个字符串的问题
- NYOJ 710
- 127个SQL server热门资料汇总
- cocos2dx 3.2 实现鼠标拖动精灵移动的效果!
- 11gR2替换OCR和VOTE
- 利用winform中DataGridView的显示较大数量的的数据
- 内存中堆和栈的区别