嗯 贴下代码 方便以后来看

treap : tyvj 普通平衡树

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<string>
  7 
  8 using namespace std;
  9 
 10 void setIO(const string& a) {
 11     freopen((a+".in").c_str(), "r", stdin);
 12     freopen((a+".out").c_str(), "w", stdout);
 13 }
 14 
 15 const int N = 200000 + 10;
 16 
 17 struct Node{
 18     int v, r, sz;
 19     Node* ch[2];
 20     Node(int v = 0) :v(v) {
 21         r = rand();
 22         sz = 1;
 23         ch[0] = ch[1] = 0;
 24     }
 25     
 26     void maintain() {
 27         sz = 1;
 28         if(ch[0]) sz += ch[0]->sz;
 29         if(ch[1]) sz += ch[1]->sz;
 30     }
 31     
 32     int cmp(int x) const {
 33         if(x == v) return -1;
 34         return x < v ? 0 : 1;
 35     }
 36 }pool[N], *pis = pool, *root = NULL;
 37 
 38 void rotate(Node*& o, int d) {
 39     Node* t = o->ch[d];
 40     o->ch[d] = t->ch[d^1];
 41     t->ch[d^1] = o;
 42     o->maintain();
 43     (o = t)->maintain();
 44 }
 45 
 46 void insert(Node*& o, int x) {
 47     if(!o) o = new(pis++) Node(x);
 48     else {
 49         int d = o->cmp(x);
 50         if(d == -1) d = 0;
 51         insert(o->ch[d], x);
 52         o->maintain();
 53         if(o->ch[d]->r < o->r) rotate(o, d);
 54     }
 55 }
 56 
 57 void remove(Node*& o, int x) {
 58     if(!o) return;
 59     int d = o->cmp(x);
 60     if(d == -1) {
 61         if(!o->ch[0]) o = o->ch[1];
 62         else if(!o->ch[1]) o = o->ch[0];
 63         else {
 64             int d2 = o->ch[0]->r < o->ch[1]->r ? 0 : 1;
 65             rotate(o, d2);
 66             remove(o->ch[d2^1], x);
 67         }
 68     }else remove(o->ch[d], x);
 69     if(o) o->maintain();
 70 }
 71 
 72 int kth(Node* o, int k) {
 73     int sz = (o->ch[0] ? o->ch[0]->sz : 0) + 1;
 74     if(sz == k) return o->v;
 75     if(sz < k) return kth(o->ch[1], k - sz);
 76     else return kth(o->ch[0], k);
 77 }
 78 
 79 int rank(int x) {
 80     int res = 0;
 81     Node* o = root;
 82     for(int d; o; o = o->ch[d]) {
 83         d = o->cmp(x);
 84         int sz = (o->ch[0] ? o->ch[0]->sz : 0) + 1;
 85         if(o->v < x) res += sz;
 86         if(d == -1) d = 0;
 87     }
 88     return res + 1;
 89 }
 90 
 91 int Pre(int x) {
 92     int res = -1;
 93     Node* o = root;
 94     for(int d; o; o = o->ch[d]) {
 95         d = o->cmp(x);
 96         if(o->v < x) res = o->v;
 97         if(d == -1) d = 0;
 98     }
 99     return res;
100 }
101 
102 int Suf(int x) {
103     int res = -1;
104     Node*o = root;
105     for(int d; o; o = o->ch[d]) {
106         d = o->cmp(x);
107         if(o->v > x) res = o->v;
108         if(d == -1) d = 1;
109     }
110     return res;
111 }
112 
113 int main() {
114 #ifdef DEBUG
115     freopen("in.txt", "r", stdin);
116     freopen("out.txt", "w", stdout);
117 #endif
118     
119     int m,opt,x;
120     for(scanf("%d",&m);m--;){
121         scanf("%d%d",&opt,&x);
122         if(opt==1) insert(root,x);
123         if(opt==2) remove(root,x);
124         if(opt==3) printf("%d
",rank(x));
125         if(opt==4) printf("%d
",kth(root, x));
126         if(opt==5) printf("%d
",Pre(x));
127         if(opt==6) printf("%d
",Suf(x));
128     }
129     
130     return 0;
131 }
View Code

splay :tvvj文艺平衡树

自顶向下,不保留父亲版本

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<string>
  7 
  8 using namespace std;
  9 
 10 void setIO(const string& a) {
 11     freopen((a+".in").c_str(), "r", stdin);
 12     freopen((a+".out").c_str(), "w", stdout);
 13 }
 14 
 15 const int N = 200000 + 10;
 16 struct Node* null;
 17 
 18 struct Node {
 19     int sz, v;
 20     Node* ch[2];
 21     bool flip;
 22     int cmp(int k) const {
 23         int s = ch[0]->sz + 1;
 24         if(k == s) return -1;
 25         return k < s ? 0 : 1;
 26     }
 27     
 28     void down() {
 29         if(!flip) return;
 30         flip = 0;
 31         swap(ch[0], ch[1]);
 32         ch[0]->flip ^= 1;
 33         ch[1]->flip ^= 1;
 34     }
 35     
 36     Node(int v = 0) : v(v) {
 37         sz = 0;
 38         ch[0] = ch[1] = null;
 39         flip = 0;
 40     }
 41     
 42     void maintain() {
 43         sz = ch[0]->sz + ch[1]->sz + 1;
 44     }
 45 }pool[N], *pis = pool, *root;
 46 
 47 void init() {
 48     null = new(pis++) Node(0);
 49     null->ch[0] = null->ch[1] = null;
 50     root = null;
 51 }
 52 
 53 int cnt = 0;
 54 
 55 void build(Node*&o, int l, int r) {
 56     if(l > r) return;
 57     int mid = (l + r) >> 1;
 58     o = new(pis++) Node();
 59     build(o->ch[0], l, mid - 1);
 60     o->v = cnt++;
 61     build(o->ch[1], mid + 1, r);
 62     o->maintain();
 63 }
 64 
 65 void rotate(Node*&o, int d) {
 66     Node* t = o->ch[d];
 67     o->ch[d] = t->ch[d^1];
 68     t->ch[d^1] = o;
 69     o->maintain();
 70     (o = t)->maintain();
 71 }
 72 
 73 void splay(Node*& o, int k) {
 74     o->down();
 75     int d = o->cmp(k);
 76     if(d == -1) return;
 77     if(d == 1) k -= o->ch[0]->sz + 1;
 78     Node*& c = o->ch[d];
 79     c->down(); 
 80     int d2 = c->cmp(k);
 81     if(d2 != -1) {
 82         if(d2 == 1) k -= c->ch[0]->sz + 1;
 83         splay(c->ch[d2], k);
 84         if(d == d2) rotate(o, d);
 85         else rotate(c, d2);
 86     }
 87     rotate(o, d);
 88 }
 89 
 90 void split(Node* o, int k, Node*& l, Node*& r) {
 91     splay(o, k);
 92     l = o;
 93     r = o->ch[1];
 94     o->ch[1] = null;
 95     o->maintain();
 96 }
 97 
 98 Node* merge(Node* l, Node* r) {
 99     splay(l, l->sz);
100     l->ch[1] = r;
101     l->maintain();
102     return l;
103 }
104 
105 void print(Node* o) {
106     if(o == null) return;
107     o->down();
108     print(o->ch[0]);
109     if(o->v) printf("%d ", o->v);
110     print(o->ch[1]);
111 }
112 
113 int main() {
114 #ifdef DEBUG
115     freopen("in.txt", "r", stdin);
116     freopen("out.txt", "w", stdout);
117 #endif
118     
119     init();
120     int n, m;
121     scanf("%d%d", &n, &m);
122     build(root, 0, n);
123     for(int i = 1; i <= m; i++) {
124         int l, r;
125         scanf("%d%d", &l, &r);
126         Node *o, *left, *mid, *right;
127         split(root, l, left, o);
128         split(o, r - l + 1, mid, right);
129         mid->flip ^= 1;
130         root = merge(merge(left, mid), right);
131     }
132     print(root);
133 
134     return 0;
135 }
View Code

自底向上,保留父亲版本

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<string>
  7 
  8 using namespace std;
  9 
 10 void setIO(const string& a) {
 11     freopen((a+".in").c_str(), "r", stdin);
 12     freopen((a+".out").c_str(), "w", stdout);
 13 }
 14 
 15 const int N = 100000 + 10;
 16 
 17 int n, m;
 18 int ch[N][2], p[N], sz[N], root;
 19 bool flip[N];
 20 
 21 #define l ch[x][0]
 22 #define r ch[x][1]
 23 
 24 void update(int x) {
 25     if(x) sz[x] = sz[l] + sz[r] + 1;
 26 }
 27 
 28 void down(int x) {
 29     if(flip[x]) {
 30         swap(l, r);
 31         flip[l] ^= 1;
 32         flip[r] ^= 1;
 33         flip[x] = 0;
 34     }
 35 }
 36 
 37 #undef l
 38 #undef r
 39 
 40 bool isroot(int x) {
 41     return p[x] != 0;
 42 }
 43 
 44 void rotate(int x) {
 45     int y = p[x], z = p[y];
 46     /*if(!isroot(y)) 不用判断么*/
 47     if(z) ch[z][ch[z][1] == y] = x;
 48     int l = ch[y][1] == x, r = l ^ 1;
 49     
 50     p[x] = z;
 51     p[y] = x;
 52     p[ch[x][r]] = y;
 53     
 54     ch[y][l] = ch[x][r];
 55     ch[x][r] = y;
 56     
 57     update(y);
 58     update(x);
 59 }
 60 
 61 void splay(int x, int FA) {
 62     static int stk[N], top;
 63     top = 0;
 64     for(int t = x; t; t = p[t]) stk[++top] = t;
 65     while(top) down(stk[top--]);
 66     while(p[x] != FA) {
 67         int y = p[x], z = p[y];
 68         if(z != FA) {
 69             if((ch[y][1] == x) ^ (ch[z][1] == y)) rotate(y);
 70             else rotate(x);
 71         }
 72         rotate(x);
 73     }
 74     if(!FA) root = x;
 75 }
 76 
 77 int cnt = 0;
 78 
 79 int build(int sz) {
 80     if(!sz) return 0;
 81     int l = build(sz >> 1);
 82     int x = ++cnt;
 83     ch[x][0] = l;
 84     int r = build(sz - (sz >> 1) - 1);
 85     ch[x][1] = r;
 86     
 87     if(l) p[l] = x;
 88     if(r) p[r] = x;
 89     
 90     update(x);
 91     return x;
 92 }
 93 
 94 int kth(int k) {
 95     for(int x = root; x;) {
 96         down(x);
 97         int s = sz[ch[x][0]] + 1;
 98         if(s == k) return x;
 99         if(s < k) k -= s, x = ch[x][1];
100         else x = ch[x][0];
101     }
102     return -1;
103 }
104 
105 void rever(int l, int r) {
106     int x = kth(l), y = kth(r + 2);
107     splay(x, 0);
108     splay(y, x);
109     flip[ch[y][0]] ^= 1;
110 }
111 
112 void print(int x) {
113     if(!x) return;
114     down(x);
115     print(ch[x][0]);
116     if(0 < x - 1 && x - 1 <= n) printf("%d ", x - 1);
117     print(ch[x][1]);
118 }
119 
120 int main() {
121 #ifdef DEBUG
122     freopen("in.txt", "r", stdin);
123     freopen("out.txt", "w", stdout);
124 #endif
125     
126     scanf("%d%d", &n, &m);
127     root = build(n + 2);
128     for(int i = 1; i <= m; i++) {
129         int l, r;
130         scanf("%d%d", &l, &r);
131         rever(l, r);
132     }
133     print(root);
134     
135     return 0;
136 }
View Code

写惯了lct反而觉得保留父亲的好写一些...而且功能强大

lct

bzoj2157

修改单点只用splay(x), modify(x), update(x)即可,发现以前竟然还要newroot(x), access(x)不知道在干什么。

改一条链要先newroot(x), access(y), splay(y);

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<string>
  7 
  8 using namespace std;
  9 
 10 void setIO(const string& a) {
 11     freopen((a+".in").c_str(), "r", stdin);
 12     freopen((a+".out").c_str(), "w", stdout);
 13 }
 14 
 15 const int N = 20000 * 2 + 10;
 16 
 17 int n, m;
 18 int ch[N][2], p[N], sz[N], mn[N], mx[N], sum[N], w[N];
 19 bool flip[N], rev[N];
 20 
 21 bool isroot(int x) {
 22     return ch[p[x]][0] != x && ch[p[x]][1] != x;
 23 }
 24 
 25 #define l ch[x][0]
 26 #define r ch[x][1]
 27 
 28 void rever(int x) {
 29     sum[x] *= -1;
 30     w[x] *= -1;
 31     swap(mn[x], mx[x]);
 32     mn[x] *= -1;
 33     mx[x] *= -1;
 34     rev[x] ^= 1;
 35 }
 36 
 37 void update(int x) {
 38     if(!x) return;
 39     sum[x] = w[x] + sum[l] + sum[r];
 40     mn[x] = min(mn[l], mn[r]);
 41     mx[x] = max(mx[l], mx[r]);
 42     if(x > n) mn[x] = min(mn[x], w[x]), mx[x] = max(mx[x], w[x]);
 43     sz[x] = sz[l] + sz[r] + 1;
 44 }
 45 
 46 void down(int x) {
 47     if(!x) return;
 48     if(flip[x]) {
 49         swap(l, r);
 50         flip[l] ^= 1;
 51         flip[r] ^= 1;
 52         flip[x] ^= 1;
 53     }
 54     if(rev[x]) {
 55         rev[x] = 0;
 56         if(l) rever(l);
 57         if(r) rever(r);
 58     }
 59 }
 60 
 61 #undef l
 62 #undef r
 63 
 64 void rotate(int x) {
 65     int y = p[x], z = p[y];
 66     int l = ch[y][1] == x, r = l ^ 1;
 67     if(!isroot(y)) ch[z][ch[z][1] == y] = x;
 68     p[y] = x;
 69     p[x] = z;
 70     p[ch[x][r]] = y;
 71     
 72     ch[y][l] = ch[x][r];
 73     ch[x][r] = y;
 74     
 75     update(y);
 76     update(x);
 77 }
 78 
 79 void splay(int x) {
 80     static int stk[N], top;
 81     stk[top = 1] = x;
 82     for(int t = x; !isroot(t); t = p[t]) stk[++top] = p[t];
 83     while(top) down(stk[top--]);
 84     
 85     while(!isroot(x)) {
 86         int y = p[x], z = p[y];
 87         if(!isroot(y)) {
 88             if((ch[y][1] == x) ^ (ch[z][1] == y)) rotate(x); else rotate(y);
 89         }
 90         rotate(x);
 91     }
 92 }
 93 
 94 void access(int x) {
 95     for(int t = 0; x; x = p[t = x]) {
 96         splay(x);
 97         ch[x][1] = t;
 98         update(x);
 99     }
100 }
101 
102 void newroot(int x) {
103     access(x);
104     splay(x);
105     flip[x] ^= 1;
106 }
107 
108 void Link(int x, int y) {
109     newroot(x);
110     p[x] = y;
111 }
112 
113 const int INF = int(1e9);
114 
115 void init() {
116     scanf("%d", &n);
117     int u, v, ww;
118     for(int i = 0; i <= n; i++) {
119         mn[i] = INF, mx[i] = -INF;
120     }
121     for(int i = 1; i < n; i++) {
122         scanf("%d%d%d", &u, &v, &ww); ++u, ++v;
123         w[i + n] = ww;
124         Link(u, i + n);
125         Link(v, i + n);
126     }
127 }
128 
129 void n_as(int x, int y) {
130     newroot(x);
131     access(y);
132     splay(y);
133 }
134 
135 void work() {
136     char opt[100];
137     int x, y;
138     for(scanf("%d", &m); m--; ) {
139         scanf("%s%d%d", opt, &x, &y);
140         if(opt[0] == 'C') {
141             int o = x + n;
142             splay(o);
143             w[o] = y;
144             update(o);
145         }else {
146             ++x, ++y;
147             n_as(x, y);
148             if(opt[0] == 'N') rever(y);
149             else if(opt[0] == 'S') printf("%d
", sum[y]);
150             else {
151                 if(opt[1] == 'I') printf("%d
", mn[y]);
152                 else printf("%d
", mx[y]);
153             }
154         }
155     }
156 }
157 
158 int main() {
159 #ifdef DEBUG
160     freopen("in.txt", "r", stdin);
161     freopen("out.txt", "w", stdout);
162 #endif
163     
164     init();
165     work();
166     
167     return 0;
168 }
View Code

链剖

bzoj1036

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<string>
  7 
  8 using namespace std;
  9 
 10 void setIO(const string& a) {
 11     freopen((a+".in").c_str(), "r", stdin);
 12     freopen((a+".out").c_str(), "w", stdout);
 13 }
 14 
 15 const int N = 30000 + 10, M = 30000 + 10, INF = ~0u>>1;
 16 
 17 int n;
 18 
 19 struct Data{
 20     int s, m;
 21     Data(int s = 0, int m = -INF) : s(s), m(m) {}
 22     Data operator + (const Data& rhs) const {
 23         return Data(s + rhs.s, max(m, rhs.m));
 24     }
 25 };
 26 
 27 struct SegmentTree{
 28     Data da[N * 4];
 29     int lft, rgt, w;
 30     
 31     #define mid ((l + r) >> 1)
 32     #define ls s << 1, l, mid
 33     #define rs s << 1 | 1, mid + 1, r
 34     
 35     void modify(int s, int l, int r) {
 36         if(l == r) {
 37             da[s] = Data(w, w);
 38             return;
 39         }
 40         if(lft <= mid) modify(ls);
 41         else modify(rs);
 42         da[s] = da[s << 1] + da[s << 1 | 1];
 43     }
 44     
 45     Data query(int s, int l, int r) {
 46         if(lft <= l && r <= rgt) return da[s];
 47         if(rgt <= mid) return query(ls);
 48         if(mid < lft) return query(rs);
 49         return query(ls) + query(rs);
 50     }
 51     
 52     void Modify(int p, int w) {
 53         lft = p, this->w = w;
 54         modify(1, 1, n);
 55     }
 56     
 57     Data Query(int l, int r) {
 58         lft = l, rgt = r;
 59         return query(1, 1, n);
 60     }
 61 }seg;
 62 
 63 struct Edge{
 64     int to;
 65     Edge* next;
 66     Edge(int to = 0, Edge* next = 0) :to(to), next(next) {}
 67 }pool[M * 2], *pis = pool, *fir[N];
 68 
 69 void AddEdge(int u, int v) {
 70     fir[u] = new(pis++) Edge(v, fir[u]);
 71     fir[v] = new(pis++) Edge(u, fir[v]);
 72 }
 73 
 74 int sz[N], fa[N], son[N], dep[N];
 75 
 76 void dfs(int u) {
 77     sz[u] = 1;
 78     son[u] = 0;
 79     for(Edge* p = fir[u]; p; p = p->next) {
 80         int v = p->to;
 81         if(v == fa[u]) continue;
 82         fa[v] = u;
 83         dep[v] = dep[u] + 1;
 84         dfs(v);
 85         sz[u] += sz[v];
 86         if(sz[v] > sz[son[u]]) son[u] = v;
 87     }
 88 }
 89 
 90 int pos[N], top[N], dfs_clk;
 91 
 92 void build(int u, int pre) {
 93     top[u] = pre;
 94     pos[u] = ++dfs_clk;
 95     if(son[u]) build(son[u], pre);
 96     for(Edge* p = fir[u]; p; p = p->next) {
 97         int v = p->to;
 98         if(v == fa[u] || v == son[u]) continue;
 99         build(v, v);
100     }
101 }
102 
103 Data query(int a, int b) {
104     int ta = top[a], tb = top[b];
105     Data res;
106     for(; ta != tb; a = fa[ta], ta = top[a]) {
107         if(dep[tb] > dep[ta]) swap(a, b), swap(ta, tb);
108         res = res + seg.Query(pos[ta], pos[a]);
109     }
110     if(dep[b] < dep[a]) swap(a, b);
111     return res + seg.Query(pos[a], pos[b]);
112 }
113 
114 int main() {
115 #ifdef DEBUG
116     freopen("in.txt", "r", stdin);
117     freopen("out.txt", "w", stdout);
118 #endif
119     
120     scanf("%d", &n);
121     for(int i = 1; i < n; i++) {
122         int u, v;
123         scanf("%d%d", &u, &v);
124         AddEdge(u, v);
125     }
126     
127     dfs(1);
128     build(1, 1);
129     
130     for(int w, i = 1; i <= n; i++) {
131         scanf("%d", &w);
132         seg.Modify(pos[i], w);
133     }
134     
135     int m, a, b;
136     scanf("%d", &m);
137     char cmd[10];
138     
139     while(m--) {
140         scanf("%s%d%d", cmd, &a, &b);
141         if(cmd[0] == 'C') seg.Modify(pos[a], b);
142         else if(cmd[1] == 'S') printf("%d
", query(a, b).s);
143         else printf("%d
", query(a, b).m);
144     }
145     
146     return 0;
147 }
View Code

以前线段树的接口有点蛋疼,现在改了一下。

没有写蛋疼的合并区间。。

stl非动态内存heap

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<string>
 7 
 8 using namespace std;
 9 
10 void setIO(const string& a) {
11     freopen((a+".in").c_str(), "r", stdin);
12     freopen((a+".out").c_str(), "w", stdout);
13 }
14 
15 const int N = 1000000 + 10;
16 
17 int a[N];
18 
19 struct Heap {
20     int da[N], sz;
21     void push(const int& x) {
22         da[sz++] = x;
23         push_heap(da, da+sz);
24     }
25     int top() const {
26         return da[0];
27     }
28     void pop() {
29         pop_heap(da, da + (sz--));
30     }
31     void init() {
32         make_heap(da, da+sz);
33     }
34 }q;
35 
36 #include<ctime>
37 #include<queue>
38 priority_queue<int> Q;
39 
40 int main() {
41 #ifdef DEBUG
42     freopen("in.txt", "r", stdin);
43     freopen("out.txt", "w", stdout);
44 #endif
45     
46     int n;
47     scanf("%d", &n);
48     for(int i = 0; i < n; i++) {
49         scanf("%d", a + i);
50     }
51     
52     int t1 = clock();
53     
54     for(int i = 0; i < n; i++) {
55         Q.push(a[i]);
56     }
57     
58     while(Q.size()) {
59 //        printf("%d ", Q.top());
60         Q.pop();
61     }
62     
63     cout << endl;
64     cout << (t1 = clock() - t1) << endl;
65     
66     for(int i = 0; i < n; i++) {
67         q.push(a[i]);
68     }
69     
70     while(q.sz) {
71 //        printf("%d ", q.top());
72         q.pop();
73     }
74     
75     cout<< endl;
76     cout << clock() - t1 << endl;
77     
78     return 0;
79 }
View Code

KM

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<iostream>
  6 
  7 using namespace std;
  8 
  9 template<typename Q> Q &read(Q &x) {
 10     static char c, f;
 11     for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1;
 12     for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0';
 13     if(f) x = -x; return x;
 14 }
 15 template<typename Q> Q read() {
 16     static Q x; read(x); return x;
 17 }
 18 
 19 const int N = 510;
 20 
 21 int n;
 22 int W[N][N];
 23 
 24 int Lx[N], Ly[N], slack[N], cy[N];
 25 bool vx[N], vy[N];
 26 
 27 bool dfs(int u) {
 28     vx[u] = 1;
 29     for(int v = 1; v <= n; v++) if(!vy[v]) {
 30         if(Lx[u] + Ly[v] == W[u][v]) {
 31             vy[v] = 1;
 32             if(!cy[v] || dfs(cy[v])) {
 33                 cy[v] = u;
 34                 return 1;
 35             }
 36         }else slack[v] = min(slack[v], Lx[u] + Ly[v] - W[u][v]);
 37     }
 38     return 0;
 39 }
 40 
 41 void update() {
 42     int a = 1 << 29;
 43     for(int i = 1; i <= n; i++) {
 44         if(!vy[i]) a = min(a, slack[i]);
 45     }
 46     for(int i = 1; i <= n; i++) {
 47         if(vx[i]) Lx[i] -= a;
 48         if(vy[i]) Ly[i] += a;
 49     }
 50 }
 51 
 52 void KM() {
 53     memset(cy, 0, sizeof cy);
 54     memset(Lx, 0, sizeof Lx);
 55     memset(Ly, 0, sizeof Ly);
 56     for(int i = 1; i <= n; i++) {
 57         for(int j = 1; j <= n; j++) {
 58             Lx[i] = max(Lx[i], W[i][j]);
 59         }
 60     }
 61     for(int i = 1; i <= n; i++) {
 62         memset(slack, 0x7f, sizeof slack);
 63         while(1) {
 64             memset(vx, 0, sizeof vx);
 65             memset(vy, 0, sizeof vy);
 66             if(dfs(i)) break;
 67             update();
 68         }
 69     }
 70 }
 71         
 72 
 73 int main() {
 74 #ifdef DEBUG
 75     freopen("in.txt", "r", stdin);
 76     freopen("out.txt", "w", stdout);
 77 #endif
 78     
 79     while(scanf("%d", &n) == 1) {
 80         for(int i = 1; i <= n; i++) {
 81             for(int j = 1; j <= n; j++) {
 82                 read(W[i][j]);
 83             }
 84         }
 85         KM();
 86         
 87         int ans = 0;
 88         for(int i = 1; i <= n; i++) {
 89             ans += Lx[i];
 90             printf("%d%c", Lx[i], " 
"[i == n]);
 91         }
 92         for(int i = 1; i <= n; i++) {
 93             ans += Ly[i];
 94             printf("%d%c", Ly[i], " 
"[i == n]);
 95         }
 96         printf("%d
", ans);
 97     }
 98     
 99     return 0;
100 }
UVa11383

手写bitset(from lcr)

 1 template<int N> struct Knapsack {
 2     const static int size = N / 32 + 10;
 3     unsigned s[size+1];
 4 
 5     void add(int x) {
 6         static int i, p, a, b;
 7         p = x >> 5;
 8         if(!(x & 31)) {
 9             for(i = size; i >= p; i--) {
10                 s[i] |= s[i - p];
11             }
12         } else {
13             a = x & 31, b = 32 - a;//这里不能写成31 ^ a..
14             for(i = size; i > p; i--) {
15                 s[i] |= s[i - p] << a;
16                 s[i] |= s[i - p - 1] >> b;
17             }
18             s[p] |= s[0] << a;
19         }
20     }
21 
22     bool operator [] (int x) const {
23         return s[x >> 5] >> (x & 31) & 1;
24     }
25 }
背包问题

tarjan求桥(可以考虑重边)

 1 struct Node {
 2     int to, id;
 3     Node(int to, int id) : to(to), id(id) {}
 4 };
 5 vector<Node> G[N];
 6 bool mark[N];
 7 int pre[N], dfs_clock;
 8 int dfs(int u, int fa) {
 9     int lowu = pre[u] = ++dfs_clock;
10     bool first = true;
11     for(unsigned i = 0; i < G[u].size(); i++) {
12         int v = G[u][i].to;
13         if(v == fa && first) {
14             first = false;
15             continue;
16         }
17         if(pre[v] == 0) {
18             int lowv = dfs(v, u);
19             lowu = min(lowu, lowv);
20             if(lowv > pre[u]) mark[G[u][i].id] = 1;
21         } else lowu = min(lowu, pre[v]);
22     }
23     return lowu;
24 }
trajan求桥

fft

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef double long_double;
 6 const int N = 1 << 20;
 7 const long_double pi = acos(-1.0);
 8 
 9 template<typename Tp> struct Complex {
10     Tp r, i;
11     Complex() {}
12     Complex(Tp r, Tp i) : r(r), i(i) {}
13     Complex operator + (const Complex &rhs) const {
14         return Complex(r + rhs.r, i + rhs.i);
15     }
16     Complex operator * (const Complex &rhs) const {
17         return Complex(r * rhs.r - i * rhs.i, i * rhs.r + r * rhs.i);
18     }
19     Complex operator - (const Complex &rhs) const {
20         return Complex(r - rhs.r, i - rhs.i);
21     }
22 };
23 
24 void FFT(Complex<long_double> a[], int n, bool inv) {
25     for(int i = 0, j = 0, k; i < n; i++) {
26         if(i < j) swap(a[i], a[j]);
27         for(k = n; j & (k >>= 1); j &= ~k);
28         j |= k;
29     }
30     long_double __pi = inv ? -pi : pi;
31     for(int i = 1; i < n; i <<= 1) {
32         Complex<long_double> rotate(cos(__pi / i), sin(__pi / i));
33         for(int k = 0; k < n; k += i << 1) {
34             Complex<long_double> w(1, 0);
35             for(int j = 0; j < i; j++) {
36                 Complex<long_double> t = w * a[i+j+k];
37                 a[i+j+k] = a[j+k] - t;
38                 a[j+k] = a[j+k] + t;
39                 w = w * rotate;
40             }
41         }
42     }
43     if(inv) for(int i = 0; i < n; i++) a[i].r /= n;
44 }
FFT

费用流

 1 struct MCMF {
 2     const int static N = 1000 + 10, M = 201000 + 10;
 3     struct Edge {
 4         int to, adv, cost;
 5         Edge *next;
 6         Edge() {}
 7         Edge(int to, int adv, int cost, Edge *next)
 8             :to(to), adv(adv), cost(cost), next(next) {}
 9     } pool[M * 2], *fir[N], *pis, *pre[N];
10 #define inv(p) (pool + ((p - pool) ^ 1))
11     int s, t;
12     void init(int s, int t) {
13         this->s = s, this->t = t;
14         memset(fir, 0, sizeof fir);
15         pis = pool;
16     }
17 
18     void AddEdge(int u, int v, int cap, int cost) {
19         fir[u] = new(pis++) Edge(v, cap, cost, fir[u]);
20         fir[v] = new(pis++) Edge(u, 0, -cost, fir[v]);
21     }
22 
23     bool SPFA(int &flow, LL &cost) {
24         static LL d[N];
25         static int q[N], ql, qr, a[N];
26         static bool inq[N];
27         memset(d, 0x3f, sizeof d);
28         ql = qr = 0;
29         d[s] = 0, a[s] = ~0u >> 1, q[qr++] = s;
30         while(ql != qr) {
31             int u = q[ql++]; inq[u] = 0; if(ql == N) ql = 0;
32             for(Edge *p = fir[u]; p; p = p->next) if(p->adv) {
33                 int v = p->to;
34                 if(d[v] > d[u] + p->cost) {
35                     d[v] = d[u] + p->cost;
36                     pre[v] = p;
37                     a[v] = min(p->adv, a[u]);
38                     if(!inq[v]) {
39                         q[qr++] = v; inq[v] = 1; if(qr == N) qr = 0;
40                     }
41                 }
42             }
43         }
44         if(d[t] == d[N-1]) return 0;
45         flow += a[t], cost += a[t] * d[t];
46         for(int u = t; u != s; u = inv(pre[u])->to) {
47             pre[u]->adv -= a[t];
48             inv(pre[u])->adv += a[t];
49         }
50         return 1;
51     }
52 
53     void main(int n, bool &suc, LL &cost, vector<int> &sol) {
54         int flow = 0; cost = 0;
55         while(SPFA(flow, cost));
56         suc = flow == n;
57         if(!suc) return;
58         for(int u = n; u < s; u++) {
59             for(Edge *p = fir[u]; p; p = p->next) if(p->to == t) {
60                 if(!p->adv) {
61                     sol.push_back(u - n);
62                     cost -= u - n;
63                 }
64             }
65         }
66     }
67 } solver;
MCMF

字符串的最小循环表示

 1 int solve(const int *s, int n) {
 2     int i = 0, j = 1, k = 0;
 3     while(i < n && j < n) {
 4         for(k = 0; s[i + k] == s[j + k] && k < n; ++k);
 5         if(k == n) return i;
 6         if(s[i + k] > s[j + k]) i = max(i + k, j) + 1;
 7         else j = max(j + k, i) + 1;
 8     }
 9     assert(i < n || j < n);
10     return min(i, j);
11 }
字符串的最小循环表示

最大流

 1 struct Dinic {
 2     const static int N = 2000 + 10, M = 10000 + 10;
 3     struct Edge {
 4         int to, adv, cap;
 5         Edge *next;
 6         Edge() {}
 7         Edge(int to, int cap, Edge *next) : to(to), adv(cap), cap(cap), next(next) {}
 8     } pool[M * 2], *fir[N], *cur[N], *pis;
 9     
10     int s, t;
11     
12     void init(int s, int t) {
13         this->s = s, this->t = t;
14         memset(fir, 0, sizeof fir), pis = pool;
15     }
16     
17     void AddEdge(int u, int v, int w) {
18         //printf("%d %d %d
", u, v, w);
19         fir[u] = new(pis++) Edge(v, w, fir[u]);
20         fir[v] = new(pis++) Edge(u, w, fir[v]);
21     }
22     
23     int d[N];
24     bool BFS() {
25         static int q[N], ql, qr;
26         ql = qr = 0;
27         memset(d, -1, sizeof d);
28         d[s] = 0, q[qr++] = s;
29         while(ql < qr) {
30             int u = q[ql++];
31             for(Edge *p = fir[u]; p; p = p->next) if(p->adv) {
32                 int v = p->to;
33                 if(d[v] == -1) {
34                     d[v] = d[u] + 1;
35                     q[qr++] = v;
36                 }
37             }
38         }
39         return d[t] != -1;
40     }
41     #define inv(p) (pool + ((p - pool) ^ 1))
42     int DFS(int u, int a) {
43         if(u == t || !a) return a;
44         int flow = 0, f;
45         for(Edge *&p = cur[u]; p; p = p->next) {
46             int v = p->to;
47             if(d[v] == d[u] + 1 && (f = DFS(v, min(p->adv, a))) > 0) {
48                 p->adv -= f;
49                 inv(p)->adv += f;
50                 flow += f;
51                 if(!(a -= f)) {
52                     break;
53                 }
54             }
55         }
56         if(!flow) d[u] = -1;
57         return flow;
58     }
59     
60     int main() {
61         int flow = 0;
62         while(BFS()) {
63             memcpy(cur, fir, sizeof cur);
64             flow += DFS(s, ~0u >> 1);
65         }
66         return flow;
67     }
68 } solver
Dinic

优化读入

1 const int D = 1 << 23;
2 char in[D], *I, *end;
3 #define getchar() (I == end ? I = in, end = in + fread(in, 1, D, stdin), *I++ : *I++)
4 template<typename Tp> void read(Tp &x) {
5     static char c, f;
6     for(f = 0; !isdigit(c = getchar()); ) f |= (c == '-');
7     for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0';
8     if(f) x = -x;
9 }
优化读入

后缀自动机

 1 struct Node *pis;
 2 struct Node {
 3     Node *par, *to[26];
 4     int maxl;
 5     
 6     Node() {}
 7     Node(int maxl) : maxl(maxl) {
 8         par = 0;
 9         memset(to, 0, sizeof to);
10     }
11     
12     void *operator new(size_t) {
13         return pis++;
14     }
15 } pool[N];
16 
17 struct Sam {
18     Node *root, *np;
19     int L;
20     
21     void init() {
22         np = root = new Node(0);
23         L = 0;
24     }
25     
26     void extend(int c) {
27         c -= 'a';
28         Node *last = np, *q, *nq;
29         np = new Node(++L);
30         for(; last && !last->to[c]; last = last->par) last->to[c] = np;
31         if(!last) np->par = root;
32         else {
33             q = last->to[c];
34             if(q->maxl == last->maxl + 1) np->par = q;
35             else {
36                 nq = new Node(*q);
37                 nq->maxl = last->maxl + 1;
38                 q->par = np->par = nq;
39                 for(; last && last->to[c] == q; last = last->par) last->to[c] = nq;
40             }
41         }
42     }
43     
44     bool excepted(const char *s) {
45         for(Node *p = root; *s; ++s) {
46             if(!p->to[*s - 'a']) return 0;
47             p = p->to[*s - 'a'];
48         }
49         return 1;
50     }
51 } sam;
sam

回文自动机

namespace pam {
    struct Node {
        int len, sz;
        Node *par, *to[26];
        Node() {}
        Node(int len, Node *par = NULL) : len(len), par(par) {}
    } pool[N], *pis, *rt[2], *last;

    void init() {
        pis = pool;
        rt[1] = new(pis++) Node(-1);
        rt[0] = new(pis++) Node(0, rt[1]);
        last = rt[1]->par = rt[1];
    }

    void extend(const char *s, int n) {
        int c = s[n] - 'a';
        Node *p = last;
        while(s[n - p->len - 1] != s[n]) p = p->par;
        if(!p->to[c]) {
            Node *q = p->par;
            while(s[n - q->len - 1] != s[n]) q = q->par;
            p->to[c] = new(pis++) Node(p->len + 2, q->to[c] ? q->to[c] : rt[0]);
        }
        (last = p->to[c])->sz++;
    }
}
pam
原文地址:https://www.cnblogs.com/showson/p/4973719.html