zoukankan      html  css  js  c++  java
  • 嗯 贴下代码 方便以后来看

    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
  • 相关阅读:
    HDU 3681 Prison Break(状态压缩dp + BFS)
    POJ 2711 Regular Words(DP + 高精度)
    ZOJ 2745 01-K Code(DP)(转)
    DAG模型——硬币问题
    HDU 1619 Unidirectional TSP(单向TSP + 路径打印)
    DAG模型——嵌套矩阵
    HDU 4294 A Famous Equation(DP)
    HDU 3920 Clear All of Them I(DP + 状态压缩 + 贪心)
    POJ 3254 Corn Fields(DP + 状态压缩)
    HDU 2089 不要62(数位DP)
  • 原文地址:https://www.cnblogs.com/showson/p/4973719.html
Copyright © 2011-2022 走看看