日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

数据结构---各种树模板

發(fā)布時(shí)間:2025/6/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构---各种树模板 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1:Trie 字典樹

字典樹

又稱單詞查找樹,Trie樹,是一種樹形結(jié)構(gòu),是一種哈希樹的變種。典型應(yīng)用是用于統(tǒng)計(jì),排序和保存大量的字符串(但不僅限于字符串),所以經(jīng)常被搜索引擎系統(tǒng)用于文本詞頻統(tǒng)計(jì)。它的優(yōu)點(diǎn)是:利用字符串的公共前綴來(lái)節(jié)約存儲(chǔ)空間,最大限度地減少無(wú)謂的字符串比較,查詢效率比哈希表高。

它有3個(gè)基本性質(zhì):根節(jié)點(diǎn)不包含字符,除根節(jié)點(diǎn)外每一個(gè)節(jié)點(diǎn)都只包含一個(gè)字符。 從根節(jié)點(diǎn)到某一節(jié)點(diǎn),路徑上經(jīng)過(guò)的字符連接起來(lái),為該節(jié)點(diǎn)對(duì)應(yīng)的字符串。 每個(gè)節(jié)點(diǎn)的所有子節(jié)點(diǎn)包含的字符都不相同。

詳細(xì)應(yīng)用見? 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];????
  • ????}????
  • }????
  • /*查詢?cè)撉熬Y出現(xiàn)次數(shù)*/????
  • /*若查詢?cè)撛~出現(xiàn)次數(shù)??
  • ??則所有的count初始化為0??
  • ??并去除所有對(duì)count的操作??
  • ??只在每次InsertTrie末尾加?p->nCount++;???
  • */?????
  • 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 樹狀數(shù)組

    1、概述

    樹狀數(shù)組(binary indexed tree),是一種設(shè)計(jì)新穎的數(shù)組結(jié)構(gòu),它能夠高效地獲取數(shù)組中連續(xù)n個(gè)數(shù)的和。概括說(shuō),樹狀數(shù)組通常用于解決以下問(wèn)題:數(shù)組{a}中的元素可能不斷地被修改,怎樣才能快速地獲取連續(xù)幾個(gè)數(shù)的和?

    2、樹狀數(shù)組基本操作

    傳統(tǒng)數(shù)組(共n個(gè)元素)的元素修改和連續(xù)元素求和的復(fù)雜度分別為O(1)和O(n)。樹狀數(shù)組通過(guò)將線性結(jié)構(gòu)轉(zhuǎn)換成偽樹狀結(jié)構(gòu)(線性結(jié)構(gòu)只能逐個(gè)掃描元素,而樹狀結(jié)構(gòu)可以實(shí)現(xiàn)跳躍式掃描),使得修改和求和復(fù)雜度均為O(lgn),大大提高了整體效率。

    詳見 : http://blog.csdn.net/metalseed/article/details/7984075? ?(含2D模板)
  • #include<iostream>????
  • #include<algorithm>????
  • using?namespace?std;????
  • ????
  • ????
  • ????
  • /*?1D?*/???????
  • const?int?maxn?=?10000;??????
  • int?tree[maxn],maxID?=?0xff/*數(shù)組長(zhǎng)度,由題定,建樹用update*/;??????
  • ??????
  • inline?void?init()??????
  • {??????
  • ????memset(tree,0,sizeof(tree));??????
  • }??????
  • ??????
  • inline?int?read(int?idx){?/*求前idx項(xiàng)和*/??????
  • ????int?sum?=?0;??????
  • ????while?(idx?>?0){??????
  • ????????sum?+=?tree[idx];??????
  • ????????idx?-=?(idx?&?-idx);??????
  • ????}??????
  • ????return?sum;??????
  • }??????
  • ????
  • inline?int?readSingle(int?idx){?/*求idx單點(diǎn)值*/????
  • ????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){??/*給idx位置疊加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 ?區(qū)間求和

  • #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;????
  • ??
  • /*?Node?Begin?*/??
  • LL?add[maxn<<2];????
  • LL?sum[maxn<<2];????
  • /*?Node?End?*/??
  • ??
  • 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 伸展樹

  • /*?
  • 題意:有N個(gè)數(shù)字圍成一個(gè)圈,有M個(gè)操作,操作類型有六種:?
  • (1)“add?x",從當(dāng)前指針位置開始的順時(shí)針K2個(gè)數(shù)加上x。?
  • (2)"reverse",翻轉(zhuǎn),從當(dāng)前指針指針位置開始的順時(shí)針的K2個(gè)數(shù)。?
  • (3)"insert?x",在當(dāng)前指針位置的順時(shí)候方向插入一個(gè)數(shù)x。?
  • (4)”delete“,刪除當(dāng)前指針?biāo)傅臄?shù)。?
  • (5)"move?x”,如果x=1,指針逆時(shí)針旋轉(zhuǎn),如果x=2,順時(shí)針旋轉(zhuǎn)。?
  • (6)“query",查詢指針?biāo)赶虻臄?shù)的值。?
  • Splay的作法就不說(shuō)了。?
  • 還可以有三個(gè)雙端隊(duì)列加兩個(gè)標(biāo)記搞定,方法,是第一個(gè)雙端隊(duì)列que1維護(hù)前K1個(gè)數(shù),?
  • 第二個(gè)que2維護(hù)第K1+1到第K2個(gè)數(shù),第三個(gè)que3維護(hù)接下的數(shù),標(biāo)記add,?
  • 表示que1和que2里的數(shù)要加上多少,標(biāo)記head,表示que1是否被翻轉(zhuǎn)過(guò)。?
  • Splay(姿勢(shì)1):?
  • */??
  • #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?Debug(){?printf("Rt:%d\n",Rt);?Travel(Rt);?}??
  • //????void?Travel(int?x)??
  • //????{??
  • //????????if(x==0)?return;??
  • //??
  • //????????PushDown(x);??
  • //????????Travel(LL(x));??
  • //????????printf("node:%d,pre:%d,sz:%d,LL:%d,RR:%d,key:%d\n",??
  • //???????????????x,pre[x],sz[x],LL(x),RR(x),key[x]);??
  • //????????Travel(RR(x));??
  • //????}??
  • ??
  • ????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(姿勢(shì)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);??
  • ????}??
  • ??
  • //????void?Debug(){?printf("Rt:%d\n",Rt);?Travel(Rt);?}??
  • //????void?Travel(int?x)??
  • //????{??
  • //????????if(x==0)?return;??
  • //????????PushDown(x);??
  • //????????Travel(LL(x));??
  • //????????printf("node:%d,sz:%d,pre:%d,LL:%d,RR:%d,key:%d\n",??
  • //???????????????x,sz[x],pre[x],LL(x),RR(x),key[x]);??
  • //????????Travel(RR(x));??
  • //????}??
  • }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);??
  • //????????????spt.Debug();??
  • ????????}??
  • ????}??
  • ????return?0;??
  • }??
  • ??
  • ??
  • /*?
  • Description?
  • ?
  • You?have?N?integers,?A1,?A2,?...?,?AN.?You?need?to?deal?with?two?kinds?of?operations.?One?type?of?operation?is?to?add?some?given?number?to?each?number?in?a?given?interval.?The?other?is?to?ask?for?the?sum?of?numbers?in?a?given?interval.?
  • ?
  • Input?
  • ?
  • The?first?line?contains?two?numbers?N?and?Q.?1?≤?N,Q?≤?100000.?
  • The?second?line?contains?N?numbers,?the?initial?values?of?A1,?A2,?...?,?AN.?-1000000000?≤?Ai?≤?1000000000.?
  • Each?of?the?next?Q?lines?represents?an?operation.?
  • "C?a?b?c"?means?adding?c?to?each?of?Aa,?Aa+1,?...?,?Ab.?-10000?≤?c?≤?10000.?
  • "Q?a?b"?means?querying?the?sum?of?Aa,?Aa+1,?...?,?Ab.?
  • ?
  • Output?
  • ?
  • You?need?to?answer?all?Q?commands?in?order.?One?answer?in?a?line.?
  • ?
  • Sample?Input?
  • ?
  • 10?5?
  • 1?2?3?4?5?6?7?8?9?10?
  • Q?4?4?
  • Q?1?10?
  • Q?2?4?
  • C?3?6?3?
  • Q?2?4?
  • Sample?Output?
  • ?
  • 4?
  • 55?
  • 9?
  • 15?
  • http://acm.pku.edu.cn/JudgeOnline/problem?id=3468?
  • 區(qū)間跟新,區(qū)間求和?
  • */??
  • #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)?{//把第k位的數(shù)轉(zhuǎn)到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)?{//把以x為祖先結(jié)點(diǎn)刪掉放進(jìn)內(nèi)存池,回收內(nèi)存??
  • ????????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("結(jié)點(diǎn)%2d:左兒子?%2d?右兒子?%2d?父結(jié)點(diǎn)?%2d?size?=?%2d?,val?=?%2d\n",x,ch[x][0],ch[x][1],pre[x],sz[x],val[x]);??
  • ????????????Treaval(ch[x][1]);??
  • ????????}??
  • ????}??
  • ????//以上Debug??
  • ???
  • ???
  • ????//以下是題目的特定函數(shù):??
  • ????inline?void?NewNode(int?&x,int?c)?{??
  • ????????if?(top2)?x?=?ss[--top2];//用棧手動(dòng)壓的內(nèi)存池??
  • ????????else?x?=?++top1;??
  • ????????ch[x][0]?=?ch[x][1]?=?pre[x]?=?0;??
  • ????????sz[x]?=?1;??
  • ???
  • ????????val[x]?=?sum[x]?=?c;/*這是題目特定函數(shù)*/??
  • ????????add[x]?=?0;??
  • ????}??
  • ???
  • ????//把延遲標(biāo)記推到孩子??
  • ????inline?void?push_down(int?x)?{/*這是題目特定函數(shù)*/??
  • ????????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;??
  • ????????}??
  • ????}??
  • ????//把孩子狀態(tài)更新上來(lái)??
  • ????inline?void?push_up(int?x)?{??????
  • ????????sz[x]?=?1?+?sz[?ch[x][0]?]?+?sz[?ch[x][1]?];??
  • ????????/*這是題目特定函數(shù)*/??
  • ????????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]);????????/*num[m]權(quán)值改成題目所需的*/??
  • ????????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)?{/*這是題目特定函數(shù)*/??
  • ????????ch[0][0]?=?ch[0][1]?=?pre[0]?=?sz[0]?=?0;??
  • ????????add[0]?=?sum[0]?=?0;??
  • ???
  • ????????root?=?top1?=?0;??
  • ????????//為了方便處理邊界,加兩個(gè)邊界頂點(diǎn)??
  • ????????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(?)?{/*這是題目特定函數(shù)*/??
  • ????????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?];??
  • ????}??
  • ????/*詢問(wèn)*/??
  • ????inline?void?query()?{/*這是題目特定函數(shù)*/??
  • ????????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:動(dòng)態(tài)樹


    8:斯坦納樹


    9:主席樹


    10:QTree


    總結(jié)

    以上是生活随笔為你收集整理的数据结构---各种树模板的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。