神奇的板子

Posted milky-w

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了神奇的板子相关的知识,希望对你有一定的参考价值。

数据结构

treap

技术分享图片
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 using namespace std;
  5 
  6 struct Node{
  7     Node *ch[2];
  8     int r,v,s,n;
  9     Node(int v):v(v){
 10         ch[0]=ch[1]=NULL;
 11         r=rand();
 12         s=n=1;
 13     }
 14     int cmp(int x) const{
 15         if(x==v) return -1;
 16         return (x<v? 0:1);
 17     }
 18     void maintain(){
 19         s=n;
 20         if(ch[0]!=NULL) s+=ch[0]->s;
 21         if(ch[1]!=NULL) s+=ch[1]->s;
 22     }
 23 };
 24 
 25 Node *root;
 26 
 27 void rotate(Node* &o,int d)
 28 {
 29     Node* k=o->ch[d^1];
 30     o->ch[d^1]=k->ch[d];
 31     k->ch[d]=o;
 32     o->maintain();
 33     k->maintain();
 34     o=k;
 35 }
 36 
 37 void insert(Node* &o,int x)
 38 {
 39     if(o==NULL) o=new Node(x);
 40     else{
 41         int d=o->cmp(x);
 42         if(d==-1) o->n+=1;
 43         else{
 44             insert(o->ch[d],x);
 45             if(o->ch[d]->r > o->r) rotate(o,d^1);
 46         }
 47     }
 48     o->maintain();
 49 }
 50 
 51 void erase(Node* &o,int x)
 52 {
 53     if(o==NULL) return;
 54     int d=o->cmp(x);
 55     if(d==-1){
 56         if(o->n>1) o->n-=1;
 57         else{
 58             if(o->ch[0]==NULL) o=o->ch[1];
 59             else if(o->ch[1]==NULL) o=o->ch[0];
 60             else{
 61                 int d2=(o->ch[0]->r > o->ch[1]->r ? 1:0);
 62                 rotate(o,d2),
 63                 erase(o->ch[d2],x);
 64             }
 65         }
 66     }
 67     else erase(o->ch[d],x);
 68     if(o!=NULL) o->maintain();
 69 }
 70 
 71 int rank(Node* o,int x)
 72 {
 73     if(o==NULL) return 1;
 74     if(o->v==x) return (o->ch[0]==NULL? 1:o->ch[0]->s+1);
 75     if(o->v >x) return rank(o->ch[0],x);
 76     return (rank(o->ch[1],x)+(o->ch[0]==NULL? 0:o->ch[0]->s)+o->n);
 77 }
 78 
 79 int kth(Node* o,int k)
 80 {
 81     if(o==NULL||o->s<k||k<=0) return 0;
 82     int t=(o->ch[0]==NULL? 0:o->ch[0]->s);
 83     if(t+1<=k&&k<=t+o->n) return o->v;
 84     if(t>=k) return kth(o->ch[0],k);
 85     return kth(o->ch[1],k-t-o->n);
 86 }
 87 
 88 int prex(Node* o,int x)
 89 {
 90     if(o==NULL) return -0x3f3f3f3f;
 91     if(o->v>=x) return prex(o->ch[0],x);
 92     return max(o->v,prex(o->ch[1],x));
 93 }
 94 
 95 int sufx(Node* o,int x)
 96 {
 97     if(o==NULL) return 0x3f3f3f3f;
 98     if(o->v<=x) return sufx(o->ch[1],x);
 99     return min(o->v,sufx(o->ch[0],x));
100 }
101 
102 int main()
103 {
104     int n;
105     scanf("%d",&n);
106     while(n--)
107     {
108         int opt,x;
109         scanf("%d%d",&opt,&x);
110         if(opt==1) insert(root,x);
111         else if(opt==2) erase(root,x);
112         else if(opt==3) printf("%d\n",rank(root,x));
113         else if(opt==4) printf("%d\n",kth(root,x));
114         else if(opt==5) printf("%d\n",prex(root,x));
115         else if(opt==6) printf("%d\n",sufx(root,x));
116     }
117     
118     return 0;
119 }
treap

 

splay

技术分享图片
  1 #include <cstdio>
  2 #include <string>
  3 
  4 inline int read() {
  5     int x = 0, f = 1;
  6     char c = getchar();
  7     while (!isdigit(c)) {
  8         if (c == -) f = -1;
  9         c = getchar();
 10     }
 11     while (isdigit(c)) {
 12         x = (x << 3) + (x << 1) + (c ^ 48);
 13         c = getchar();
 14     }
 15     return x * f;
 16 }
 17 
 18 struct Node {
 19     int val, size, tag;
 20     Node *ch[2];
 21     inline int cmp(int v) {
 22         return val > v ? 0 : 1;
 23     }
 24     inline void maintain() {
 25         size = 1;
 26         if (ch[0] != NULL) size += ch[0]->size;
 27         if (ch[1] != NULL) size += ch[1]->size;
 28     }
 29     inline void pushdown() {
 30         Node *tmp = ch[0]; ch[0] = ch[1], ch[1] = tmp;
 31         if (ch[0] != NULL) ch[0]->tag ^= 1; 
 32         if (ch[1] != NULL) ch[1]->tag ^= 1;
 33         tag = 0;
 34     }
 35     Node (int v = 0) : val(v) {size = 1, tag = 0, ch[0] = ch[1] = NULL;}
 36 } *root;
 37 
 38 void insert(Node* &cur, int val) {
 39     if (cur == NULL) cur = new Node(val);
 40     else {
 41         insert(cur->ch[cur->cmp(val)], val);
 42         cur->maintain();
 43     }
 44 }
 45 
 46 inline void rotate(Node* &cur, int d) {
 47     Node* nxt = cur->ch[d];
 48     if (nxt->tag) nxt->pushdown();
 49     cur->ch[d] = nxt->ch[d^1], nxt->ch[d^1] = cur;
 50     cur->maintain(), nxt->maintain();
 51     cur = nxt;
 52 }
 53 
 54 void splay(Node* &cur, int k) {
 55     if (cur->tag) cur->pushdown();
 56     int l = cur->ch[0] == NULL ? 0 : cur->ch[0]->size;
 57     if (l + 1 == k) return;
 58     int d = k <= l ? 0 : 1;
 59     int k2 = d ? k - l - 1 : k;
 60     Node* &nxt = cur->ch[d];
 61     if (nxt->tag) nxt->pushdown();
 62     int l2 = nxt->ch[0] == NULL ? 0 : nxt->ch[0]->size;
 63     if (l2 + 1 != k2) {
 64         int d2 = k2 <= l2 ? 0 : 1;
 65         splay(nxt->ch[d2], d2? k2 - l2 - 1 : k2);
 66         if (d == d2) rotate(cur, d);
 67         else rotate(nxt, d2);
 68     }
 69     rotate(cur, d);
 70 }
 71 
 72 inline int kth(Node* &cur, int k) {
 73     splay(cur, k);
 74     return cur->val;
 75 }
 76 
 77 int main() {
 78     int n = read(), m = read();
 79     for (register int i = 1; i <= n; ++ i) {
 80         insert(root, i);
 81         splay(root, i);
 82     }
 83     for (register int i = 1; i <= m; ++ i) {
 84         int l = read(), r = read();
 85         if (l == 1 && r == n) {
 86             root->tag ^= 1;
 87         } else if (l == 1) {
 88             splay(root, r + 1);
 89             root->ch[0]->tag ^= 1;
 90         } else if (r == n) {
 91             splay(root, l - 1);
 92             root->ch[1]->tag ^= 1;
 93         } else {
 94             splay(root, l - 1);
 95             splay(root -> ch[1], r - (root->ch[0] == NULL ? 0 : root->ch[0]->size));
 96             root->ch[1]->ch[0]->tag ^= 1;
 97         }
 98     }
 99     for (register int i = 1; i <= n; ++ i)
100         printf("%d ", kth(root, i));
101     puts("");
102     return 0;
103 }
splay

 

字符串

trie

技术分享图片
 1 struct Trie {
 2     int ch[500005][26], val[500005], size;
 3     Trie() {size = 1; memset(ch[0], 0, sizeof ch[0]);}
 4     inline int idx(char c) {return c - a;}
 5     
 6     inline void insert(char *s, int v) {
 7         int u = 0, n = strlen(s);
 8         for (register int i = 0; i < n; ++ i) {
 9             int c = idx(s[i]);
10             if (!ch[u][c]) {
11                 memset(ch[size], 0, sizeof ch[size]);
12                 val[size] = 0;
13                 ch[u][c] = size++;
14             }
15             u = ch[u][c];
16         }
17         val[u] = v;
18     }
19     
20     inline int find(char *s) {
21         int u = 0, n = strlen(s);
22         for (register int i = 0; i < n; ++ i) {
23             int c = idx(s[i]);
24             if (!ch[u][c]) return 0;
25             else u = ch[u][c];
26         }
27         if (val[u] == 0) return 0;
28         return 1;
29     }
30 } trie;
trie

 

KMP

技术分享图片
 1 void getNext()
 2 {
 3     int m=strlen(W);
 4     nxt[0]=nxt[1]=0;
 5     for(int i=1;i<m;++i)
 6     {
 7         int j=nxt[i];
 8         while(j && W[i]!=W[j]) j=nxt[j];
 9         if(W[i]==W[j]) nxt[i+1]=j+1;
10     }
11 }
12 
13 void KMP()
14 {
15     int n=strlen(S),m=strlen(W);
16     getNext();
17     int j=0;
18     for(int i=0;i<n;++i)
19     {
20         while(j && S[i]!=W[j]) j=nxt[j];
21         if(S[i]==W[j]) ++j;
22         if(j==m) printf("%d\n",i-m+2);
23     }
24 }
KMP

 

AC自动机

 

后缀数组

 

后缀平衡树

以上是关于神奇的板子的主要内容,如果未能解决你的问题,请参考以下文章

PHP必用代码片段

效率神奇Github丧心病狂的9个狠招

out参数不用赋值?这么神奇吗!

hdu4009最小树形图板子题

out参数不用赋值?这么神奇吗!

几个关于js数组方法reduce的经典片段