生活随笔
收集整理的這篇文章主要介紹了
数据结构---各种树模板
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1:Trie 字典樹
字典樹
又稱單詞查找樹,Trie樹,是一種樹形結構,是一種哈希樹的變種。典型應用是用于統計,排序和保存大量的字符串(但不僅限于字符串),所以經常被搜索引擎系統用于文本詞頻統計。它的優點是:利用字符串的公共前綴來節約存儲空間,最大限度地減少無謂的字符串比較,查詢效率比哈希表高。
它有3個基本性質:根節點不包含字符,除根節點外每一個節點都只包含一個字符。 從根節點到某一節點,路徑上經過的字符連接起來,為該節點對應的字符串。 每個節點的所有子節點包含的字符都不相同。
詳細應用見?
http://blog.csdn.net/metalseed/article/details/7953262
#include?<iostream>????using?namespace?std;????#define?MAX?26?//字符集大小????????typedef?struct?TrieNode?{????????int?nCount;????????struct?TrieNode?*next[MAX];????}TrieNode;????????TrieNode?Memory[1000000];????int?allocp?=0;????????TrieNode?*CreateTrieNode()?{????????int?i;????????TrieNode?*p;????????p?=?&Memory[allocp++];????????p->nCount?=?1;????????for(i?=0?;?i?<?MAX?;?i++)?{????????????p->next[i]?=?NULL;????????}????????return?p;????}????????void?InsertTrie(TrieNode?*?&pRoot?,?char*s)?{????????int?i,?k;????????TrieNode?*p;????????if(!(p?=?pRoot))?{????????????p?=?pRoot?=?CreateTrieNode();????????}????????i?=?0;????????while(s[i])?{????????????k?=?s[i++]?-?'a';????????????if(p->next[k])????????????????p->next[k]->nCount++;????????????else????????????????p->next[k]?=?CreateTrieNode();????????????p?=?p->next[k];????????}????}?????????????????int?SearchTrie(TrieNode?*?&pRoot?,?char*s)?{????????TrieNode?*p;????????int?i?,?k;????????if(!(p?=?pRoot))?{????????????return?0;????????}????????i?=?0;????????while(s[i])?{????????????k?=?s[i++]?-'a';????????????if(p->next[k]?==?NULL)?return?0;????????????p?=?p->next[k];????????}????????return?p->nCount;????}????????int?main()????{????????TrieNode?*ROOT?=?NULL;????????InsertTrie(ROOT,"see");????????InsertTrie(ROOT,"seeda");????????InsertTrie(ROOT,"seedb");????????InsertTrie(ROOT,"seeda");????????cout<<SearchTrie(ROOT,"seeda")<<endl;????????cout<<SearchTrie(ROOT,"seedb")<<endl;????????cout<<SearchTrie(ROOT,"see")<<endl;????????return?0;????}????
3:BIT 樹狀數組
1、概述
樹狀數組(binary indexed tree),是一種設計新穎的數組結構,它能夠高效地獲取數組中連續n個數的和。概括說,樹狀數組通常用于解決以下問題:數組{a}中的元素可能不斷地被修改,怎樣才能快速地獲取連續幾個數的和?
2、樹狀數組基本操作
傳統數組(共n個元素)的元素修改和連續元素求和的復雜度分別為O(1)和O(n)。樹狀數組通過將線性結構轉換成偽樹狀結構(線性結構只能逐個掃描元素,而樹狀結構可以實現跳躍式掃描),使得修改和求和復雜度均為O(lgn),大大提高了整體效率。
詳見 :
http://blog.csdn.net/metalseed/article/details/7984075? ?(含2D模板)
#include<iostream>????#include<algorithm>????using?namespace?std;???????????????????????const?int?maxn?=?10000;??????int?tree[maxn],maxID?=?0xff;????????????inline?void?init()??????{??????????memset(tree,0,sizeof(tree));??????}????????????inline?int?read(int?idx){???????????int?sum?=?0;??????????while?(idx?>?0){??????????????sum?+=?tree[idx];??????????????idx?-=?(idx?&?-idx);??????????}??????????return?sum;??????}??????????inline?int?readSingle(int?idx){?????????int?sum?=?tree[idx];????????if?(idx?>?0){????????????int?z?=?idx?-?(idx?&?-idx);????????????idx--;?????????????while?(idx?!=?z){????????????????sum?-=?tree[idx];?????????????????idx?-=?(idx?&?-idx);????????????}????????}????????return?sum;????}????????inline?void?update(int?idx?,int?val){???????????while?(idx?<=?maxID){??????????????tree[idx]?+=?val;??????????????idx?+=?(idx?&?-idx);??????????}??????}?????????????????int?main()????{????????cout?<<?read(10)?<<?endl;????????for(int?i?=?0;?i<?10;?++i)????????{????????????update(i+1,i+1);????????}????????update(4,999);????????cout?<<?read(1)?<<?endl;????????cout?<<?read(3)?<<?endl;????????????????cout?<<?readSingle(4)?<<?endl;????????return?0;????}????
4:Segment Tree 線段樹
成段加C ?區間求和
#include?<cstdio>????#include?<algorithm>????using?namespace?std;?????????#define?lson?l?,?m?,?rt?<<?1????#define?rson?m?+?1?,?r?,?rt?<<?1?|?1????#define?LL?long?long????const?int?maxn?=?111111;????????LL?add[maxn<<2];????LL?sum[maxn<<2];????????void?PushUp(int?rt)?{????????sum[rt]?=?sum[rt<<1]?+?sum[rt<<1|1];????}????void?PushDown(int?rt,int?m)?{????????if?(add[rt])?{????????????add[rt<<1]?+=?add[rt];????????????add[rt<<1|1]?+=?add[rt];????????????sum[rt<<1]?+=?add[rt]?*?(m?-?(m?>>?1));????????????sum[rt<<1|1]?+=?add[rt]?*?(m?>>?1);????????????add[rt]?=?0;????????}????}????void?build(int?l,int?r,int?rt)?{????????add[rt]?=?0;????????if?(l?==?r)?{????????????scanf("%lld",&sum[rt]);????????????return?;????????}????????int?m?=?(l?+?r)?>>?1;????????build(lson);????????build(rson);????????PushUp(rt);????}????void?update(int?L,int?R,int?c,int?l,int?r,int?rt)?{????????if?(L?<=?l?&&?r?<=?R)?{????????????add[rt]?+=?c;????????????sum[rt]?+=?(LL)c?*?(r?-?l?+?1);????????????return?;????????}????????PushDown(rt?,?r?-?l?+?1);????????int?m?=?(l?+?r)?>>?1;????????if?(L?<=?m)?update(L?,?R?,?c?,?lson);????????if?(m?<?R)?update(L?,?R?,?c?,?rson);????????PushUp(rt);????}????LL?query(int?L,int?R,int?l,int?r,int?rt)?{????????if?(L?<=?l?&&?r?<=?R)?{????????????return?sum[rt];????????}????????PushDown(rt?,?r?-?l?+?1);????????int?m?=?(l?+?r)?>>?1;????????LL?ret?=?0;????????if?(L?<=?m)?ret?+=?query(L?,?R?,?lson);????????if?(m?<?R)?ret?+=?query(L?,?R?,?rson);????????return?ret;????}????int?main()?{????????int?N?,?Q;????????scanf("%d%d",&N,&Q);????????build(1?,?N?,?1);????????while?(Q?--)?{????????????char?op[2];????????????int?a?,?b?,?c;????????????scanf("%s",op);????????????if?(op[0]?==?'Q')???????????{????????????????scanf("%d%d",&a,&b);????????????????printf("%lld\n",query(a?,?b?,?1?,?N?,?1));????????????}???????????else???????????{????????????????scanf("%d%d%d",&a,&b,&c);????????????????update(a?,?b?,?c?,?1?,?N?,?1);????????????}????????}????????return?0;????}????
5:SBT 二叉平衡檢索樹
http://acm.hdu.edu.cn/showproblem.php?pid=4006
#include?<stdio.h>??#include?<string.h>??#define?MAX?1000010??????int?n,m;??struct?SBT?{????????int?left,right,size,key;??????void?Init()?{????????????left?=?right?=?0;??????????size?=?1;??????}??}a[MAX];??int?tot,root;??????void?left_rotate(int?&t)?{????????int?k?=?a[t].right;??????a[t].right?=?a[k].left;??????a[k].left?=?t;??????a[k].size?=?a[t].size;??????a[t].size?=?a[a[t].left].size?+?a[a[t].right].size?+?1;??????t?=?k;??}??void?right_rotate(int?&t)?{????????int?k?=?a[t].left;??????a[t].left?=?a[k].right;??????a[k].right?=?t;??????a[k].size?=?a[t].size;??????a[t].size?=?a[a[t].left].size?+?a[a[t].right].size?+?1;??????t?=?k;??}??void?maintain(int?&t,int?flag)?{????????if?(flag?==?0)?{????????????if?(a[a[a[t].left].left].size?>?a[a[t].right].size)???????????????right_rotate(t);??????????else?if?(a[a[a[t].left].right].size?>?a[a[t].right].size)??????????????left_rotate(a[t].left),right_rotate(t);??????????else?return;??????}??????else?{????????????if?(a[a[a[t].right].right].size?>?a[a[t].left].size)??????????????left_rotate(t);??????????else?if?(a[a[a[t].right].left].size?>?a[a[t].left].size)??????????????right_rotate(a[t].right),left_rotate(t);??????????else?return;??????}??????maintain(a[t].left,0);??????maintain(a[t].right,1);??????maintain(t,0);??????maintain(t,1);??}??void?insert(int?&t,int?v)?{????????if?(t?==?0)??????????t?=?++tot,a[t].Init(),a[t].key?=?v;??????else?{????????????a[t].size++;??????????if?(v?<?a[t].key)??????????????insert(a[t].left,v);??????????else?insert(a[t].right,v);??????????maintain(t,v>=a[t].key);??????}??}??int?del(int?&t,int?v)?{????????if?(!t)?return?0;??????a[t].size--;????????if?(v?==?a[t].key?||?v?<?a[t].key?&&?!a[t].left??????????||?v?>?a[t].key?&&?!a[t].right)?{????????????if?(a[t].left?&&?a[t].right)?{????????????????int?p?=?del(a[t].left,v+1);??????????????a[t].key?=?a[p].key;??????????????return?p;??????????}??????????else?{????????????????int?p?=?t;??????????????t?=?a[t].left?+?a[t].right;??????????????return?p;??????????}??????}??????else?return?del(v<a[t].key?a[t].left:a[t].right,v);??}??int?find(int?t,int?k)?{????????if?(k?<=?a[a[t].left].size)??????????return?find(a[t].left,k);??????if?(k?>?a[a[t].left].size?+?1)??????????return?find(a[t].right,k-a[a[t].left].size-1);??????return?a[t].key;??}??????int?main()??{??????int?i,j,k;??????????while?(scanf("%d%d",&n,&m)?!=?EOF)?{????????????tot?=?root?=?0;??????????char?ope[10];??????????while?(n--)?{????????????????scanf("%s",ope);??????????????if?(ope[0]?==?'I')?{????????????????????scanf("%d",&k);??????????????????insert(root,k);??????????????}??????????????else?printf("%d\n",find(root,a[root].size+1-m));??????????}??????}??}??
6:Splay 伸展樹
???????????????#include?<iostream>??#include?<cstdio>??#include?<cstring>??#include?<string>??#include?<vector>??#include?<algorithm>??#include?<queue>??#include?<set>??#include?<map>??using?namespace?std;????typedef?long?long?LL;??typedef?pair<int,int>?PII;????#define?LL(x)????(ch[x][0])??#define?RR(x)????(ch[x][1])??#define?Kt???????(ch[?ch[Rt][1]?][0])??#define?MID(a,b)?(a+((b-a)>>1))????const?int?N=1e6+5;????int?n,m,k1,k2;??int?a[N/2];????struct?SplayTree??{??????int?Rt,top;??????int?pre[N],sz[N],ch[N][2];????????int?key[N],add[N],pos;??????bool?flip[N];????????inline?void?Link(int?x,int?y,int?f)??????{??????????pre[x]=y;?if(y)?ch[y][f]=x;??????}??????inline?void?Rotate(int?x,int?f)??????{??????????int?y=pre[x],z=pre[y];????????????PushDown(y);?PushDown(x);????????????Link(x,z,RR(z)==y);??????????Link(ch[x][f],y,!f);??????????Link(y,x,f);????????????PushUp(y);??????}??????inline?void?Splay(int?x,int?goal)??????{??????????while(pre[x]!=goal)??????????{??????????????int?y=pre[x],z=pre[y];??????????????int?cx=(LL(y)==x),cy=(LL(z)==y);??????????????if(z==goal)?Rotate(x,cx);??????????????else??????????????{??????????????????if(cx==cy)?Rotate(y,cy);??????????????????else?Rotate(x,cx);??????????????????Rotate(x,cy);??????????????}??????????}??????????PushUp(x);??????????if(goal==0)?Rt=x;??????}??????inline?void?Select(int?K,int?goal)??????{??????????int?x=Rt;??????????PushDown(x);??????????while(1)??????????{??????????????if(sz[LL(x)]>=K)?x=LL(x);??????????????else?if(sz[LL(x)]+1==K)?break;??????????????else?K-=sz[LL(x)]+1,x=RR(x);??????????????PushDown(x);??????????}??????????Splay(x,goal);??????}????????inline?void?fun_add(int?x,int?valu)??????{??????????add[x]+=valu;??????????key[x]+=valu;??????}??????inline?void?fun_flip(int?x)??????{??????????flip[x]^=1;??????????swap(LL(x),RR(x));??????}??????inline?void?PushDown(int?x)??????{??????????if(add[x])??????????{??????????????fun_add(LL(x),add[x]);??????????????fun_add(RR(x),add[x]);??????????????add[x]=0;??????????}??????????if(flip[x])??????????{??????????????fun_flip(LL(x));??????????????fun_flip(RR(x));??????????????flip[x]=0;??????????}??????}??????inline?void?PushUp(int?x)??????{??????????sz[x]=1+sz[LL(x)]+sz[RR(x)];??????}??????inline?void?Add(int?x)??????{??????????Select(1,0);?Select(k2+2,Rt);??????????fun_add(Kt,x);??????}??????inline?void?Reverse()??????{??????????Select(1,0);?Select(k1+2,Rt);??????????fun_flip(Kt);??????}??????inline?void?Insert(int?x,int?pos)??????{??????????Select(pos,0);?Select(pos+1,Rt);??????????addNode(x,Kt,RR(Rt));??????????PushUp(RR(Rt));?PushUp(Rt);??????}??????inline?int?Delete(bool?top)??????{??????????int?valu;??????????if(top)??????????{??????????????Select(1,0);????Select(3,Rt);??????????????valu=key[Kt];??????????????Kt=0;??????????????PushUp(RR(Rt));?PushUp(Rt);??????????}??????????else??????????{??????????????int?len=sz[Rt];??????????????Select(len-2,0);Select(len,Rt);??????????????valu=key[Kt];??????????????Kt=0;??????????????PushUp(RR(Rt));?PushUp(Rt);??????????}??????????return?valu;??????}??????inline?void?Move(int?x)??????{??????????if(x==1)??????????{??????????????int?valu=Delete(0);??????????????Insert(valu,1);??????????}??????????else??????????{??????????????int?valu=Delete(1);??????????????Insert(valu,sz[Rt]-1);??????????}??????}??????inline?void?Query()??????{??????????Select(2,0);??????????printf("%d\n",key[Rt]);??????}????????????????????????????????void?addNode(int?valu,int?&x,int?f)??????{??????????x=++top;??????????pre[x]=f;?sz[x]=1;?LL(x)=RR(x)=0;????????????key[x]=valu;?add[x]=flip[x]=0;??????}??????void?build(int?lft,int?rht,int?&x,int?f)??????{??????????if(lft>rht)?return;????????????int?mid=MID(lft,rht);??????????addNode(a[mid],x,f);??????????build(lft,mid-1,LL(x),x);??????????build(mid+1,rht,RR(x),x);??????????PushUp(x);??????}??????void?init()??????{??????????Rt=top=0;??????????pre[0]=sz[0]=LL(0)=RR(0)=0;????????????addNode(0,Rt,0);????addNode(0,RR(Rt),Rt);??????????build(0,n-1,Kt,RR(Rt));??????????PushUp(RR(Rt));?????PushUp(Rt);??????}??}spt;??int?main()??{??????int?t_cnt=0;??????while(scanf("%d%d%d%d",&n,&m,&k1,&k2)!=EOF)??????{??????????if(n==0&&m==0&&k1==0&&k2==0)?break;????????????for(int?i=0;i<n;i++)?scanf("%d",&a[i]);????????????spt.init();????????????printf("Case?#%d:\n",++t_cnt);????????????char?op[100];?int?x;??????????while(m--)??????????{??????????????scanf("%s",op);??????????????if(op[0]=='a')??????????????{??????????????????scanf("%d",&x);?spt.Add(x);??????????????}??????????????else?if(op[0]=='r')?spt.Reverse();??????????????else?if(op[0]=='i')??????????????{??????????????????scanf("%d",&x);?spt.Insert(x,2);??????????????}??????????????else?if(op[0]=='d')?spt.Delete(1);??????????????else?if(op[0]=='m')??????????????{??????????????????scanf("%d",&x);?spt.Move(x);??????????????}??????????????else?spt.Query();??????????}??????}??????return?0;??}??????Spaly(姿勢2):????#include?<iostream>??#include?<cstdio>??#include?<cstring>??using?namespace?std;????#define?LL(x)?(ch[x][0])??#define?RR(x)?(ch[x][1])??#define?Kt????(ch[?ch[Rt][1]?][0])??#define?MID(a,b)???(a+((b-a)>>1))????const?int?N=1e6+5;????int?a[N/2];??int?n,m,K1,K2,pos;????struct?SplayTree??{??????int?Rt,top;??????int?sz[N],pre[N],ch[N][2];????????bool?flip[N];??????int?key[N],add[N];????????inline?void?Link(int?x,int?y,int?f)??????{??????????pre[x]=y;?if(y)?ch[y][f]=x;??????}??????inline?void?Rotate(int?x,int?f)??????{??????????int?y=pre[x],z=pre[y];????????????PushDown(y);?PushDown(x);??????????Link(x,z,RR(z)==y);??????????Link(ch[x][f],y,!f);??????????Link(y,x,f);??????????PushUp(y);??????}??????inline?void?Splay(int?x,int?goal)??????{??????????while(pre[x]!=goal)??????????{??????????????int?y=pre[x],z=pre[y];??????????????int?cx=(LL(y)==x),cy=(LL(z)==y);??????????????if(z==goal)?Rotate(x,cx);??????????????else??????????????{??????????????????if(cx==cy)?Rotate(y,cy);??????????????????else?Rotate(x,cx);??????????????????Rotate(x,cy);??????????????}??????????}??????????PushUp(x);??????????if(goal==0)?Rt=x;??????}??????inline?void?Select(int?K,int?goal)??????{??????????int?x=Rt;??????????PushDown(x);??????????while(1)??????????{??????????????if(sz[LL(x)]>=K)?x=LL(x);??????????????else?if(1+sz[LL(x)]==K)?break;??????????????else?K-=sz[LL(x)]+1,x=RR(x);??????????????PushDown(x);??????????}??????????Splay(x,goal);??????}????????inline?void?fun_add(int?x,int?valu)??????{??????????key[x]+=valu;??????????add[x]+=valu;??????}??????inline?void?fun_flip(int?x)??????{??????????flip[x]^=1;??????????swap(LL(x),RR(x));??????}??????inline?void?PushUp(int?x)??????{??????????sz[x]=1+sz[LL(x)]+sz[RR(x)];??????}??????inline?void?PushDown(int?x)??????{??????????if(add[x])??????????{??????????????fun_add(LL(x),add[x]);??????????????fun_add(RR(x),add[x]);??????????????add[x]=0;??????????}??????????if(flip[x])??????????{??????????????fun_flip(LL(x));?fun_flip(RR(x));??????????????flip[x]=0;??????????}??????}??????inline?void?Add(int?st,int?ed,int?valu)??????{??????????Select(st-1,0);?Select(ed+1,Rt);??????????fun_add(Kt,valu);??????}??????inline?void?Reverse(int?st,int?ed)??????{??????????Select(st-1,0);?Select(ed+1,Rt);??????????fun_flip(Kt);??????}??????inline?void?Insert(int?pos,int?valu)??????{??????????Select(pos,0);??Select(pos+1,Rt);??????????addNode(valu,Kt,RR(Rt));??????????PushUp(RR(Rt));?PushUp(Rt);??????}??????inline?void?Delete(int?pos)??????{??????????Select(pos-1,0);?Select(pos+1,Rt);??????????Kt=0;??PushUp(RR(Rt));?PushUp(Rt);??????}??????inline?void?Query(int?pos)??????{??????????Select(pos,0);??????????printf("%d\n",key[Rt]);??????}??????inline?void?Move(int?len)??????{??????????pos-=len;??????????Select(1,0);????Select(2+len,Rt);??????????int?r1=Kt;??????Kt=0;??????????PushUp(RR(Rt));?PushUp(Rt);????????????Select(sz[Rt]-1,0);?Select(sz[Rt],Rt);??????????Link(r1,RR(Rt),0);??????????PushUp(RR(Rt));?PushUp(Rt);??????}????????inline?void?addNode(int?valu,int?&x,int?f)??????{??????????x=++top;????????????sz[x]=1;?pre[x]=f;?LL(x)=RR(x)=0;????????????key[x]=valu;?add[x]=flip[x]=0;??????}??????void?build(int?lft,int?rht,int?&x,int?f)??????{??????????if(lft>rht)?return;????????????int?mid=MID(lft,rht);??????????addNode(a[mid],x,f);??????????build(lft,mid-1,LL(x),x);??????????build(mid+1,rht,RR(x),x);??????????PushUp(x);??????}??????void?init()??????{??????????Rt=top=0;????????????addNode(0,Rt,0);?addNode(0,RR(Rt),Rt);????????????build(0,n-1,Kt,RR(Rt));??????????PushUp(RR(Rt));??PushUp(Rt);??????}????????????????????????}spt;??void?deal(int?&pos,int?len)??{??????if(pos<=1)?pos=len-1;??????if(pos>=len)?pos=2;??}??int?main()??{??????freopen("in.txt","r",stdin);????????int?t_cnt=0;??????while(scanf("%d%d%d%d",&n,&m,&K1,&K2)!=EOF)??????{??????????if(n==0&&m==0&&K1==0&&K2==0)?break;????????????for(int?i=0;i<n;i++)?scanf("%d",&a[i]);????????????spt.init();?pos=2;????????????printf("Case?#%d:\n",++t_cnt);????????????char?op[100];?int?x;??????????while(m--)??????????{??????????????int?len=spt.sz[spt.Rt];??????????????scanf("%s",op);??????????????if(op[0]=='a')??????????????{??????????????????scanf("%d",&x);??????????????????if(pos+K2>len)?spt.Move(pos+K2-len);??????????????????spt.Add(pos,pos+K2-1,x);??????????????}??????????????else?if(op[0]=='r')??????????????{??????????????????if(pos+K1>=len)?spt.Move(pos+K1-len);??????????????????spt.Reverse(pos,pos+K1-1);??????????????}??????????????else?if(op[0]=='i')??????????????{??????????????????scanf("%d",&x);?spt.Insert(pos,x);??????????????}??????????????else?if(op[0]=='d')??????????????{??????????????????spt.Delete(pos);??????????????????deal(pos,spt.sz[spt.Rt]);??????????????}??????????????else?if(op[0]=='m')??????????????{??????????????????scanf("%d",&x);??????????????????if(x==1)?pos--;??????????????????else?pos++;??????????????????deal(pos,len);??????????????}??????????????else?if(op[0]=='q')?spt.Query(pos);????????????}??????}??????return?0;??}??????????????????????????????????????????#include?<cstdio>??#define?keyTree?(ch[?ch[root][1]?][0])??const?int?maxn?=?222222;??struct?SplayTree{??????int?sz[maxn];??????int?ch[maxn][2];??????int?pre[maxn];??????int?root?,?top1?,?top2;??????int?ss[maxn]?,?que[maxn];?????????inline?void?Rotate(int?x,int?f)?{??????????int?y?=?pre[x];??????????push_down(y);??????????push_down(x);??????????ch[y][!f]?=?ch[x][f];??????????pre[?ch[x][f]?]?=?y;??????????pre[x]?=?pre[y];??????????if(pre[x])?ch[?pre[y]?][?ch[pre[y]][1]?==?y?]?=?x;??????????ch[x][f]?=?y;??????????pre[y]?=?x;??????????push_up(y);??????}??????inline?void?Splay(int?x,int?goal)?{??????????push_down(x);??????????while(pre[x]?!=?goal)?{??????????????if(pre[pre[x]]?==?goal)?{??????????????????Rotate(x?,?ch[pre[x]][0]?==?x);??????????????}?else?{??????????????????int?y?=?pre[x]?,?z?=?pre[y];??????????????????int?f?=?(ch[z][0]?==?y);??????????????????if(ch[y][f]?==?x)?{??????????????????????Rotate(x?,?!f)?,?Rotate(x?,?f);??????????????????}?else?{??????????????????????Rotate(y?,?f)?,?Rotate(x?,?f);??????????????????}??????????????}??????????}??????????push_up(x);??????????if(goal?==?0)?root?=?x;??????}??????inline?void?RotateTo(int?k,int?goal)?{??????????int?x?=?root;??????????push_down(x);??????????while(sz[?ch[x][0]?]?!=?k)?{??????????????if(k?<?sz[?ch[x][0]?])?{??????????????????x?=?ch[x][0];??????????????}?else?{??????????????????k?-=?(sz[?ch[x][0]?]?+?1);??????????????????x?=?ch[x][1];??????????????}??????????????push_down(x);??????????}??????????Splay(x,goal);??????}??????inline?void?erase(int?x)?{??????????int?father?=?pre[x];??????????int?head?=?0?,?tail?=?0;??????????for?(que[tail++]?=?x?;?head?<?tail?;?head?++)?{??????????????ss[top2?++]?=?que[head];??????????????if(ch[?que[head]?][0])?que[tail++]?=?ch[?que[head]?][0];??????????????if(ch[?que[head]?][1])?que[tail++]?=?ch[?que[head]?][1];??????????}??????????ch[?father?][?ch[father][1]?==?x?]?=?0;??????????pushup(father);??????}????????????void?debug()?{printf("%d\n",root);Treaval(root);}??????void?Treaval(int?x)?{??????????if(x)?{??????????????Treaval(ch[x][0]);??????????????printf("結點%2d:左兒子?%2d?右兒子?%2d?父結點?%2d?size?=?%2d?,val?=?%2d\n",x,ch[x][0],ch[x][1],pre[x],sz[x],val[x]);??????????????Treaval(ch[x][1]);??????????}??????}????????????????????????inline?void?NewNode(int?&x,int?c)?{??????????if?(top2)?x?=?ss[--top2];??????????else?x?=?++top1;??????????ch[x][0]?=?ch[x][1]?=?pre[x]?=?0;??????????sz[x]?=?1;?????????????val[x]?=?sum[x]?=?c;??????????add[x]?=?0;??????}???????????????inline?void?push_down(int?x)?{??????????if(add[x])?{??????????????val[x]?+=?add[x];??????????????add[?ch[x][0]?]?+=?add[x];??????????????add[?ch[x][1]?]?+=?add[x];???????????????sum[?ch[x][0]?]?+=?(long?long)sz[?ch[x][0]?]?*?add[x];??????????????sum[?ch[x][1]?]?+=?(long?long)sz[?ch[x][1]?]?*?add[x];??????????????add[x]?=?0;??????????}??????}????????????inline?void?push_up(int?x)?{??????????????sz[x]?=?1?+?sz[?ch[x][0]?]?+?sz[?ch[x][1]?];????????????????????sum[x]?=?add[x]?+?val[x]?+?sum[?ch[x][0]?]?+?sum[?ch[x][1]?];??????}???????????????inline?void?makeTree(int?&x,int?l,int?r,int?f)?{??????????if(l?>?r)?return?;??????????int?m?=?(l?+?r)>>1;??????????NewNode(x?,?num[m]);??????????????????makeTree(ch[x][0]?,?l?,?m?-?1?,?x);??????????makeTree(ch[x][1]?,?m?+?1?,?r?,?x);??????????pre[x]?=?f;??????????push_up(x);??????}??????inline?void?init(int?n)?{??????????ch[0][0]?=?ch[0][1]?=?pre[0]?=?sz[0]?=?0;??????????add[0]?=?sum[0]?=?0;?????????????root?=?top1?=?0;????????????????????NewNode(root?,?-1);??????????NewNode(ch[root][1]?,?-1);??????????pre[top1]?=?root;??????????sz[root]?=?2;????????????????for?(int?i?=?0?;?i?<?n?;?i?++)?scanf("%d",&num[i]);??????????makeTree(keyTree?,?0?,?n-1?,?ch[root][1]);??????????push_up(ch[root][1]);??????????push_up(root);??????}????????????inline?void?update(?)?{??????????int?l?,?r?,?c;??????????scanf("%d%d%d",&l,&r,&c);??????????RotateTo(l-1,0);??????????RotateTo(r+1,root);???????????????add[?keyTree?]?+=?c;??????????sum[?keyTree?]?+=?(long?long)c?*?sz[?keyTree?];??????}????????????inline?void?query()?{??????????int?l?,?r;??????????scanf("%d%d",&l,&r);??????????RotateTo(l-1?,?0);??????????RotateTo(r+1?,?root);??????????printf("%lld\n",sum[keyTree]);??????}??????????????????int?num[maxn];??????int?val[maxn];??????int?add[maxn];??????long?long?sum[maxn];??}spt;????????int?main()?{??????int?n?,?m;??????scanf("%d%d",&n,&m);??????spt.init(n);??????while(m?--)?{??????????char?op[2];??????????scanf("%s",op);??????????if(op[0]?==?'Q')?{??????????????spt.query();??????????}?else?{??????????????spt.update();??????????}??????}??????return?0;??}??
7:動態樹
8:斯坦納樹
9:主席樹
10:QTree
總結
以上是生活随笔為你收集整理的数据结构---各种树模板的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。