zoukankan      html  css  js  c++  java
  • 2016 Multi-University Training Contest 2

    1001 Acperience

    1002 Born Slippy

    考虑链上版本,有dp[i] = max{dp[j] + opt(w[i], w[j])}

    由于w的范围是2^16,拆成前8位后8位。

    引入辅助ds[x][y]表示dp[j]前8位是x,dp[i]后8位是y时的max{dp[j] + opt(dp[j]后8位, dp[i]后8位)}

    这样的好处是,更新dp[i]时,由于dp[i]的后8位和前8位都是已知的,只要用2^8枚举dp[j]的前8位,假设为k

    得到dp[i] = max{ds[k][y] + (opt(k, dp[i]前8位) << 8)}

    然后再更新ds数组,枚举后继的dp值后8位,假设为k,ds[dp[i]前8位][k] = max{dp[i] + opt(dp[i]后8位, k)}

    再考虑树上版本,因为每次改ds只会改255个值,在更新ds前先备份一下,回溯的时候还原即可。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 typedef long long LL;
     7 const LL mod = 1e9 + 7;
     8 const int maxn = 66666;
     9 LL w[maxn], dp[maxn], ds[256][256], cpy[maxn][256];
    10 char opt[11];
    11 
    12 // edge
    13 int cnt, h[maxn];
    14 void init()
    15 {
    16     cnt = 0;
    17     memset(h, 0, sizeof(h));
    18 }
    19 struct edge
    20 {
    21     int to, pre;
    22 } e[maxn];
    23 void add(int from, int to)
    24 {
    25     cnt++;
    26     e[cnt].pre = h[from];
    27     e[cnt].to = to;
    28     h[from] = cnt;
    29 }
    30 
    31 // dp
    32 LL F(LL A, LL B)
    33 {
    34     if(opt[0] == 'A') return A & B;
    35     if(opt[0] == 'X') return A ^ B;
    36     return A | B;
    37 }
    38 void dfs(int x)
    39 {
    40     dp[x] = 0;
    41     LL A = w[x] >> 8, B = w[x] & 255;
    42     for(int i = 0; i <= 255; i++)
    43     if(ds[i][B] != -1) dp[x] = max(dp[x], ds[i][B] + (F(i, A) << 8));
    44 
    45     for(int i = 0; i <= 255; i++)
    46     {
    47         cpy[x][i] = ds[A][i];
    48         ds[A][i] = max(ds[A][i], dp[x] + F(i, B));
    49     }
    50     for(int i = h[x]; i; i = e[i].pre) dfs(e[i].to);
    51     for(int i = 0; i <= 255; i++) ds[A][i] = cpy[x][i];
    52 }
    53 
    54 int main(void)
    55 {
    56     memset(ds, -1, sizeof(ds));
    57     int T;
    58     scanf("%d", &T);
    59     while(T--)
    60     {
    61         init();
    62         int n;
    63         scanf("%d %s", &n, opt);
    64         for(int i = 1; i <= n; i++) scanf("%d", w + i);
    65         for(int i = 2; i <= n; i++)
    66         {
    67             int f;
    68             scanf("%d", &f);
    69             add(f, i);
    70         }
    71 
    72         dfs(1);
    73         LL ans = 0;
    74         for(int i = 1; i <= n; i++) ans = (ans + i * (dp[i] + w[i])) % mod;
    75         printf("%I64d
    ", ans);
    76 
    77     }
    78     return 0;
    79 }
    Aguin

    1003 Call It What You Want

    1004 Differencia

    在每个线段树节点[l, r]维护排好序的b[l]-b[r]。

    每次修改,在每个区间内二分小于等于x的数有几个,就得到一个nlognlogn的做法。

    再维护对于[l, r]内第i大的数,在左子树中,有多少数字小于等于它,存在L[p][i]里,右子树同理。

    然后每次修改,在根节点二分,找有多少个数小于等于x,

    然后下传到左右子树的时候,x是多少已经不重要了,只要知道第一个小于等于x的数在什么位置,

    只要考虑左子树有多少数小于等于L[p][i],右子树有多少数小于等于R[p][i]。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 using namespace std;
      5 typedef long long LL;
      6 const int mod = 1e9 + 7;
      7 const int maxn = 1e5 + 10;
      8 const int C = ~(1<<31), M = (1<<16)-1;
      9 int a[maxn], b[maxn], A, B;
     10 int all[maxn], t1[maxn], t2[maxn];
     11 
     12 struct node
     13 {
     14     int id, x;
     15     node() {}
     16     node(int ID, int X): id(ID), x(X) {}
     17     friend bool operator < (node A, node B)
     18     {
     19         return A.x < B.x;
     20     }
     21 } t[maxn];
     22 
     23 // segment_tree
     24 int sum[maxn<<2], tag[maxn<<2];
     25 int *L[maxn<<2], *R[maxn<<2];
     26 
     27 void gather(int p)
     28 {
     29     sum[p] = sum[p<<1] + sum[p<<1|1];
     30 }
     31 
     32 void push(int p)
     33 {
     34     if(tag[p] != -1)
     35     {
     36         int rk = tag[p];
     37         sum[p<<1] = tag[p<<1] = L[p][rk];
     38         sum[p<<1|1] = tag[p<<1|1] = R[p][rk];
     39         tag[p] = -1;
     40     }
     41 }
     42 
     43 void init(int p, int l, int r)
     44 {
     45     int mid = (l + r) >> 1;
     46     L[p] = new int[r - l + 10];
     47     R[p] = new int[r - l + 10];
     48     if(l != r) init(p<<1, l, mid), init(p<<1|1, mid + 1, r);
     49 }
     50 
     51 void build(int p, int l, int r)
     52 {
     53     tag[p] = -1;
     54     L[p][0] = R[p][0] = 0;
     55 
     56     if(l < r)
     57     {
     58         int mid = (l + r) >> 1;
     59 
     60         int ct = 0, ct1 = 0, ct2 = 0;
     61         t[ct++].x = 0, t1[ct1++] = 0, t2[ct2++] = 0;
     62         for(int i = l; i <= mid; i++) t[ct].x = b[i], t[ct++].id = 0;
     63         for(int i = mid + 1; i <= r; i++) t[ct].x = b[i], t[ct++].id = 1;
     64 
     65         sort(t, t + ct);
     66         for(int i = 1; i < ct; i++)
     67         {
     68             if(!t[i].id) t1[ct1++] = t[i].x;
     69             else t2[ct2++] = t[i].x;
     70         }
     71 
     72         int p1 = ct1 = 0, p2 = ct2 = 0;
     73         for(int i = 1; i <= r - l + 1; i++)
     74         {
     75             while(p1 <= mid - l && t1[p1+1] <= t[i].x) p1++;
     76             while(p2 < r - mid && t2[p2+1] <= t[i].x) p2++;
     77             L[p][++ct1] = p1, R[p][++ct2] = p2;
     78         }
     79 
     80         build(p<<1, l, mid);
     81         build(p<<1|1, mid + 1, r);
     82         gather(p);
     83     }
     84     else
     85     {
     86         L[p][1] = R[p][1] = 1;
     87         sum[p] = a[l] >= b[l];
     88     }
     89 }
     90 
     91 void modify(int p, int tl, int tr, int l, int r, int rk)
     92 {
     93     if(tr < l || r < tl) return;
     94     if(l <= tl && tr <= r)
     95     {
     96         sum[p] = tag[p] = rk;
     97         return;
     98     }
     99     push(p);
    100     int mid = (tl + tr) >> 1;
    101     modify(p<<1, tl, mid, l, r, L[p][rk]);
    102     modify(p<<1|1, mid+1, tr, l, r, R[p][rk]);
    103     gather(p);
    104 }
    105 
    106 int query(int p, int tl, int tr, int l, int r)
    107 {
    108     if(tr < l || r < tl) return 0;
    109     if(l <= tl && tr <= r) return sum[p];
    110     push(p);
    111     int mid = (tl + tr) >> 1;
    112     int ret = query(p<<1, tl, mid, l, r);
    113     ret += query(p<<1|1, mid+1, tr, l, r);
    114     return ret;
    115 }
    116 
    117 
    118 int rnd(int last)
    119 {
    120     A = (36969 + (last >> 3)) * (A & M) + (A >> 16);
    121     B = (18000 + (last >> 3)) * (B & M) + (B >> 16);
    122     return (C & ((A << 16) + B)) % 1000000000;
    123 }
    124 
    125 
    126 int main(void)
    127 {
    128     init(1, 1, maxn);
    129     int T;
    130     scanf("%d", &T);
    131     while(T--)
    132     {
    133 
    134         int n, m;
    135         scanf("%d %d %d %d", &n, &m, &A, &B);
    136         for(int i = 1; i <= n; i++) scanf("%d", a + i);
    137         for(int i = 1; i <= n; i++) scanf("%d", b + i);
    138 
    139         all[0] = 0;
    140         for(int i = 1; i <= n; i++) all[i] = b[i];
    141         sort(all, all + n + 1);
    142 
    143         build(1, 1, n);
    144 
    145         int ans = 0;
    146         int last = 0;
    147         for(int i = 1; i <= m; i++)
    148         {
    149             int l = rnd(last) % n + 1, r = rnd(last) % n + 1, x = rnd(last) + 1;
    150             if(l > r) swap(l, r);
    151             if((l + r + x) % 2)
    152             {
    153                 int rk = x >= all[n] ? n : lower_bound(all, all + n + 1, x + 1) - all - 1;
    154                 modify(1, 1, n, l, r, rk);
    155             }
    156             else
    157             {
    158                 last = query(1, 1, n, l, r);
    159                 ans = (ans + (LL) i * (LL) last) % mod;
    160             }
    161         }
    162 
    163         printf("%d
    ", ans);
    164 
    165     }
    166     return 0;
    167 }
    Aguin

    1005 Eureka

    先按x排序,然后扫一遍所有点,后面点极角排序,数贡献。

    感觉自己的计数好像弄复杂了……

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const LL mod = 1e9 + 7;
    LL Pow[1111];
    
    int gcd(int a, int b)
    {
        return a % b ? gcd(b, a % b) : b;
    }
    
    struct point
    {
        int x, y;
    } p[1111], tmp[1111];
    
    bool cmp1(point A, point B)
    {
        if(A.x != B.x) return A.x < B.x;
        return A.y < B.y;
    }
    
    bool cmp2(point A, point B)
    {
        return 1.0 * A.y * B.x < 1.0 * B.y * A.x;
    }
    
    int main(void)
    {
        Pow[0] = 1;
        for(int i = 1; i <= 1000; i++) Pow[i] = Pow[i-1] * 2 % mod;
    
        int T;
        scanf("%d", &T);
        while(T--)
        {
            int n;
            scanf("%d", &n);
            for(int i = 1; i <= n; i++) scanf("%d %d", &p[i].x, &p[i].y);
            sort(p + 1, p + 1 + n, cmp1);
    
            LL ans = 0;
            for(int i = 1; i <= n; i++)
            {
                int cnt1 = 1, cnt2 = 0;
                for(int j = i + 1; j <= n; j++)
                {
                    if(p[j].x == p[i].x && p[j].y == p[i].y) cnt1++;
                    else
                    {
                        tmp[cnt2].x = p[j].x - p[i].x;
                        tmp[cnt2].y = p[j].y - p[i].y;
                        if(!tmp[cnt2].x) tmp[cnt2].y /= abs(tmp[cnt2].y);
                        else if(!tmp[cnt2].y) tmp[cnt2].x /= abs(tmp[cnt2].x);
                        else
                        {
                            int g = gcd(abs(tmp[cnt2].x), abs(tmp[cnt2].y));
                            tmp[cnt2].x /= g, tmp[cnt2].y /= g;
                        }
                        cnt2++;
                    }
                }
                sort(tmp, tmp + cnt2, cmp2);
                int pos = 0, cnt = 1;
                LL all = (Pow[cnt1] - cnt1 - 1 + mod) % mod;
                while(pos < cnt2)
                {
                    while(pos < cnt2 - 1 && tmp[pos].x == tmp[pos+1].x && tmp[pos].y == tmp[pos+1].y) pos++, cnt++;
                    ans = (ans + Pow[cnt1+cnt] - Pow[cnt] - cnt1 - all + mod + mod) % mod;
                    pos++, cnt = 1;
                }
                ans = (ans + all) % mod;
                i += cnt1 - 1;
            }
            printf("%I64d
    ", ans);
        }
        return 0;
    }
    Aguin

    1006 Fantasia

    看了这里的图才懂。

    这个方法可以把所有的非孤立点和新加的点搞成一棵树。

    dp一下能算出每个子树的子树乘积和孩子和。再统计一下。孤立点要另外算。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 #include <stack>
      6 #include <algorithm>
      7 using namespace std;
      8 typedef pair<int, int> pii;
      9 typedef long long LL;
     10 const LL mod = 1e9 + 7;
     11 const int maxn = 1e5 + 10;
     12 LL sum[maxn<<1], pro[maxn<<1];
     13 
     14 bool single[maxn], vis[maxn<<1];
     15 int w[maxn];
     16 int n;
     17 vector<int> rt;
     18 
     19 
     20 // edge
     21 int cnt[2], h[2][maxn<<1];
     22 void init()
     23 {
     24     cnt[0] = cnt[1] = 0;
     25     memset(h, -1, sizeof(h));
     26 }
     27 struct edge
     28 {
     29     int to, pre;
     30     bool used;
     31 } e[2][maxn<<2];
     32 void add(int i, int from, int to)
     33 {
     34     e[i][cnt[i]].pre = h[i][from];
     35     e[i][cnt[i]].to = to;
     36     e[i][cnt[i]].used = 0;
     37     h[i][from] = cnt[i]++;
     38 }
     39 
     40 
     41 // BCC
     42 int pre[maxn], bccno[maxn], dfs_clock, bcc_cnt;
     43 stack<pii> S;
     44 int dfs(int u, int fa)
     45 {
     46     int lowu = pre[u] = ++dfs_clock;
     47     if(h[0][u] == -1) {single[u] = 1; return lowu;}
     48     for(int i = h[0][u]; i != -1; i = e[0][i].pre)
     49     {
     50         // multi-edge
     51         if(e[0][i].used) continue;
     52         e[0][i].used = e[0][i^1].used = 1;
     53 
     54         int v = e[0][i].to;
     55         pii E = pii(u, v);
     56         if(!pre[v])
     57         {
     58             S.push(E);
     59             int lowv = dfs(v, u);
     60             lowu = min(lowu, lowv);
     61             if(lowv >= pre[u])
     62             {
     63                 bcc_cnt++;
     64                 while(1)
     65                 {
     66                     pii x = S.top(); S.pop();
     67                     if(bccno[x.first] != bcc_cnt)
     68                     {
     69                         bccno[x.first] = bcc_cnt;
     70                         add(1, x.first, n + bcc_cnt);
     71                         add(1, n + bcc_cnt, x.first);
     72                     }
     73                     if(bccno[x.second] != bcc_cnt)
     74                     {
     75                         bccno[x.second] = bcc_cnt;
     76                         add(1, x.second, n + bcc_cnt);
     77                         add(1, n + bcc_cnt, x.second);
     78                     }
     79                     if(x.first == u && x.second == v) break;
     80                 }
     81             }
     82         }
     83         else if(pre[v] < pre[u] && v != fa)
     84         {
     85             S.push(E);
     86             lowu = min(lowu, pre[v]);
     87         }
     88     }
     89     return lowu;
     90 }
     91 
     92 void find_bcc()
     93 {
     94     memset(pre, 0, sizeof(pre));
     95     memset(bccno, 0, sizeof(bccno));
     96     memset(single, 0, sizeof(single));
     97     dfs_clock = bcc_cnt = 0;
     98     for(int i = 1; i <= n; i++)
     99         if(!pre[i]) dfs(i, -1);
    100 }
    101 
    102 
    103 // tree_dp
    104 int id[maxn<<1];
    105 void dfs2(int x, int ID)
    106 {
    107     id[x] = ID, vis[x] = 1;
    108     sum[x] = 0, pro[x] = x > n ? 1 : w[x];
    109     for(int i = h[1][x]; i != -1; i = e[1][i].pre)
    110     {
    111         int to = e[1][i].to;
    112         if(vis[to]) continue;
    113         dfs2(to, ID);
    114         sum[x] = (sum[x] + pro[to]) % mod;
    115         pro[x] = (pro[x] * pro[to]) % mod;
    116     }
    117 }
    118 
    119 
    120 // inv
    121 LL qpow(LL a, LL b)
    122 {
    123     LL ret = 1LL;
    124     while(b)
    125     {
    126         if(b & 1) ret = ret * a % mod;
    127         a = a * a % mod;
    128         b >>= 1;
    129     }
    130     return ret;
    131 }
    132 LL inv(LL x)
    133 {
    134     return qpow(x, mod - 2);
    135 }
    136 
    137 
    138 int main(void)
    139 {
    140 
    141     int T;
    142     scanf("%d", &T);
    143     while(T--)
    144     {
    145         int m;
    146         scanf("%d %d", &n, &m);
    147         for(int i = 1; i <= n; i++) scanf("%d", w + i);
    148         init();
    149         for(int i = 1; i <= m; i++)
    150         {
    151             int u, v;
    152             scanf("%d %d", &u, &v);
    153             add(0, u, v), add(0, v, u);
    154         }
    155         find_bcc();
    156 
    157         rt.clear();
    158         memset(vis, 0, sizeof(vis));
    159         for(int i = 1; i <= bcc_cnt; i++)
    160         {
    161             if(vis[n+i]) continue;
    162             rt.push_back(i + n);
    163             dfs2(i + n, i + n);
    164         }
    165 
    166         LL tot = 0;
    167         for(int i = 1; i <= n; i++) if(single[i]) tot = (tot + w[i]) % mod;
    168         int sz = rt.size();
    169         for(int i = 0; i < sz; i++) tot = (tot + pro[rt[i]]) % mod;
    170 
    171         LL ans = 0;
    172         for(int i = 1; i <= n; i++)
    173         {
    174             if(single[i]) ans = (ans + (LL) i * (tot - w[i] + mod) % mod) % mod;
    175             else ans = (ans + LL(i) * (tot - pro[id[i]] + mod + pro[id[i]] * inv(pro[i]) % mod + sum[i]) % mod) % mod;
    176         }
    177 
    178         printf("%I64d
    ", ans);
    179 
    180     }
    181     return 0;
    182 }
    Aguin

    1007 Glorious Brilliance

    先预处理一下最短路和路径。

    然后给每个联通块染色,如果可行的话跑最小费用流。

    要注意的是左右点数相等的时候,涂色方案有两种,都要考虑,取代价小的。

    输出路径的时候,每次找到第一个两端颜色不同的边开始换位置。

    不会写函数还讨论了颜色导致代码非常丑。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 #include <queue>
      6 #include <algorithm>
      7 using namespace std;
      8 typedef pair<int, int> pii;
      9 vector<pii> tmp, v1, v2, path;
     10 int n;
     11 
     12 // Floyd
     13 int G[555][555], mid[555][555];
     14 void Floyd()
     15 {
     16     memset(mid, 0, sizeof(mid));
     17     for(int k = 1; k <= n; k++)
     18     {
     19         for(int i = 1; i <= n; i++)
     20         {
     21             for(int j = 1; j <= n; j++)
     22             {
     23                 if(G[i][j] > G[i][k] + G[k][j])
     24                 {
     25                     mid[i][j] = k;
     26                     G[i][j] = G[i][k] + G[k][j];
     27                 }
     28             }
     29         }
     30     }
     31 }
     32 
     33 void get_path(int i, int j)
     34 {
     35     if(mid[i][j]) get_path(i, mid[i][j]), get_path(mid[i][j], j);
     36     else path.push_back(pii(i, j));
     37 }
     38 
     39 // BG_draw
     40 int c0, c1, n0, n1;
     41 int cl[555];
     42 int nc[555], used[555], id[555];
     43 bool draw(int x, int c, int no)
     44 {
     45     used[x] = 1, nc[x] = c, id[x] = no;
     46     if(cl[x]) c1++; else c0++;
     47     if(c) n1++; else n0++;
     48     for(int i = 1; i <= n; i++)
     49     {
     50         if(G[x][i] != 1 || used[i]) continue;
     51         if(!draw(i, c^1, no)) return false;
     52     }
     53     return true;
     54 }
     55 
     56 void flip(int x)
     57 {
     58     swap(n0, n1);
     59     for(int i = 1; i <= n; i++) if(id[i] == x) nc[i] ^= 1;
     60 }
     61 
     62 
     63 //SPFA_min_cost_flow
     64 const int INF = 1e9;
     65 const int maxn = 1e6;
     66 int dist[555], vis[555];
     67 int pv[555], pe[555];
     68 int cnt, h[555];
     69 
     70 struct edge
     71 {
     72     int to, pre, cap, cost;
     73 } e[maxn<<1];
     74 
     75 void init()//Don't forget
     76 {
     77     cnt = 0;
     78     memset(h, -1, sizeof(h));
     79 }
     80 
     81 void add(int from, int to, int cap, int cost)
     82 {
     83     e[cnt].pre = h[from];
     84     e[cnt].to = to;
     85     e[cnt].cap = cap;
     86     e[cnt].cost = cost;
     87     h[from] = cnt;
     88     cnt++;
     89 }
     90 
     91 void ad(int from, int to, int cap, int cost)
     92 {
     93     add(from, to, cap, cost);
     94     add(to, from, 0, -cost);
     95 }
     96 
     97 int min_cost_flow(int s, int t, int f)
     98 {
     99     int ret = 0;
    100     while(f > 0)
    101     {
    102         memset(vis, 0, sizeof(vis));
    103         for(int i = 0; i < 555; i++) dist[i] = INF;
    104         dist[s] = 0;
    105         queue<int> q;
    106         q.push(s);
    107         while(!q.empty())
    108         {
    109             int v = q.front(); q.pop();
    110             vis[v] = 0;
    111             for(int i = h[v]; i >= 0; i = e[i].pre)
    112             {
    113                 int to = e[i].to, cap = e[i].cap, cost = e[i].cost;
    114                 if(cap > 0 && dist[to] > dist[v] + cost)
    115                 {
    116                     pv[to] = v, pe[to] = i;
    117                     dist[to] = dist[v] + cost;
    118                     if(!vis[to]) q.push(to);
    119                     vis[to] = 1;
    120                 }
    121             }
    122         }
    123 
    124         if(dist[t] == INF) return -1;//modify here
    125 
    126         int d = f;
    127         for(int v = t; v != s; v = pv[v])
    128             d = min(d, e[pe[v]].cap);
    129         f -= d;
    130         ret += d * dist[t];
    131         for(int v = t; v != s; v = pv[v])
    132         {
    133             e[pe[v]].cap -= d;
    134             e[pe[v]^1].cap += d;
    135         }
    136     }
    137     return ret;
    138 }
    139 
    140 
    141 int main(void)
    142 {
    143     int T;
    144     scanf("%d", &T);
    145     while(T--)
    146     {
    147         int m;
    148         scanf("%d %d", &n, &m);
    149         char s[555];
    150         scanf("%s", s + 1);
    151         for(int i = 1; i <= n; i++) cl[i] = s[i] - '0';
    152         for(int i = 1; i <= n; i++)
    153             for(int j = 1; j <= n; j++)
    154                 G[i][j] = i == j ? 0 : INF;
    155         for(int i = 1; i <= m; i++)
    156         {
    157             int u, v;
    158             scanf("%d %d", &u, &v);
    159             G[u][v] = G[v][u] = 1;
    160         }
    161 
    162         Floyd();
    163 
    164         int ok = 1, ans = 0;
    165         tmp.clear();
    166         memset(id, 0, sizeof(id));
    167         memset(used, 0, sizeof(used));
    168         for(int i = 1; i <= n; i++)
    169         {
    170             if(used[i]) continue;
    171 
    172             c0 = c1 = n0 = n1 = 0;
    173             if(!draw(i, 0, i)) {ok = 0; break;}
    174 
    175             if(c0 == c1 && n0 == n1)
    176             {
    177                 init();
    178                 int f = 0;
    179                 int S = n + 1, T = S + 1;
    180                 for(int u = 1; u <= n; u++)
    181                 {
    182                     if(id[u] != i) continue;
    183                     if(cl[u] == nc[u]) continue;
    184 
    185                     if(cl[u])
    186                     {
    187                         ad(S, u, 1, 0), f++;
    188                         for(int v = 1; v <= n; v++)
    189                         {
    190                             if(id[v] != i) continue;
    191                             if(cl[v] == nc[v] || cl[u] == cl[v]) continue;
    192                             ad(u, v, 1, G[u][v]);
    193                         }
    194                     }
    195                     else ad(u, T, 1, 0);
    196                 }
    197 
    198                 int flow1 = min_cost_flow(S, T, f);
    199                 v1.clear();
    200                 for(int u = 1; u <= n; u++)
    201                 {
    202                     if(id[u] != i) continue;
    203                     if(cl[u] == nc[u] || !cl[u]) continue;
    204                     for(int j = h[u]; j >= 0; j = e[j].pre)
    205                         if(e[j].to != S && !e[j].cap) v1.push_back(pii(u, e[j].to));
    206                 }
    207 
    208                 init(), flip(i), f = 0;
    209                 for(int u = 1; u <= n; u++)
    210                 {
    211                     if(id[u] != i) continue;
    212                     if(cl[u] == nc[u]) continue;
    213 
    214                     if(cl[u])
    215                     {
    216                         ad(S, u, 1, 0), f++;
    217                         for(int v = 1; v <= n; v++)
    218                         {
    219                             if(id[v] != i) continue;
    220                             if(cl[v] == nc[v] || cl[u] == cl[v]) continue;
    221                             ad(u, v, 1, G[u][v]);
    222                         }
    223                     }
    224                     else ad(u, T, 1, 0);
    225                 }
    226 
    227                 int flow2 = min_cost_flow(S, T, f);
    228                 v2.clear();
    229                 for(int u = 1; u <= n; u++)
    230                 {
    231                     if(id[u] != i) continue;
    232                     if(cl[u] == nc[u] || !cl[u]) continue;
    233                     for(int j = h[u]; j >= 0; j = e[j].pre)
    234                         if(e[j].to != S && !e[j].cap) v2.push_back(pii(u, e[j].to));
    235                 }
    236 
    237                 if(flow1 <= flow2)
    238                 {
    239                     ans += flow1;
    240                     flip(i);
    241                     int sz = v1.size();
    242                     for(int j = 0; j < sz; j++)
    243                     {
    244                         int u = v1[j].first, v = v1[j].second;
    245                         path.clear(), get_path(u, v);
    246                         int sp = path.size(), last = 0;
    247                         for(int k = 0; k < sp; k++)
    248                         if(cl[path[k].first] != cl[path[k].second])
    249                         {
    250                             for(int r = k; r >= last; r--)
    251                             {
    252                                 tmp.push_back(path[r]);
    253                                 swap(cl[path[r].first], cl[path[r].second]);
    254                             }
    255                             last = k + 1;
    256                         }
    257                     }
    258                 }
    259                 else
    260                 {
    261                     ans += flow2;
    262                     int sz = v2.size();
    263                     for(int j = 0; j < sz; j++)
    264                     {
    265                         int u = v2[j].first, v = v2[j].second;
    266                         path.clear(), get_path(u, v);
    267                         int sp = path.size(), last = 0;
    268                         for(int k = 0; k < sp; k++)
    269                         if(cl[path[k].first] != cl[path[k].second])
    270                         {
    271                             for(int r = k; r >= last; r--)
    272                             {
    273                                 tmp.push_back(path[r]);
    274                                 swap(cl[path[r].first], cl[path[r].second]);
    275                             }
    276                             last = k + 1;
    277                         }
    278                     }
    279                 }
    280 
    281             }
    282 
    283             else if(c0 == n0 && c1 == n1)
    284             {
    285                 init();
    286                 int f = 0;
    287                 int S = n + 1, T = S + 1;
    288                 for(int u = 1; u <= n; u++)
    289                 {
    290                     if(id[u] != i) continue;
    291                     if(cl[u] == nc[u]) continue;
    292 
    293                     if(cl[u])
    294                     {
    295                         ad(S, u, 1, 0), f++;
    296                         for(int v = 1; v <= n; v++)
    297                         {
    298                             if(id[v] != i) continue;
    299                             if(cl[v] == nc[v] || cl[u] == cl[v]) continue;
    300                             ad(u, v, 1, G[u][v]);
    301                         }
    302                     }
    303                     else ad(u, T, 1, 0);
    304                 }
    305 
    306                 int flow1 = min_cost_flow(S, T, f);
    307                 v1.clear();
    308                 for(int u = 1; u <= n; u++)
    309                 {
    310                     if(id[u] != i) continue;
    311                     if(cl[u] == nc[u] || !cl[u]) continue;
    312                     for(int j = h[u]; j >= 0; j = e[j].pre)
    313                         if(e[j].to != S && !e[j].cap) v1.push_back(pii(u, e[j].to));
    314                 }
    315 
    316                 ans += flow1;
    317                 int sz = v1.size();
    318                 for(int j = 0; j < sz; j++)
    319                 {
    320                     int u = v1[j].first, v = v1[j].second;
    321                     path.clear(), get_path(u, v);
    322                     int sp = path.size(), last = 0;
    323                     for(int k = 0; k < sp; k++)
    324                     if(cl[path[k].first] != cl[path[k].second])
    325                     {
    326                         for(int r = k; r >= last; r--)
    327                         {
    328                             tmp.push_back(path[r]);
    329                             swap(cl[path[r].first], cl[path[r].second]);
    330                         }
    331                         last = k + 1;
    332                     }
    333                 }
    334 
    335             }
    336 
    337             else if(c0 == n1 && c1 == n0)
    338             {
    339                 init(), flip(i);
    340                 int f = 0;
    341                 int S = n + 1, T = S + 1;
    342                 for(int u = 1; u <= n; u++)
    343                 {
    344                     if(id[u] != i) continue;
    345                     if(cl[u] == nc[u]) continue;
    346 
    347                     if(cl[u])
    348                     {
    349                         ad(S, u, 1, 0), f++;
    350                         for(int v = 1; v <= n; v++)
    351                         {
    352                             if(id[v] != i) continue;
    353                             if(cl[v] == nc[v] || cl[u] == cl[v]) continue;
    354                             ad(u, v, 1, G[u][v]);
    355                         }
    356                     }
    357                     else ad(u, T, 1, 0);
    358                 }
    359 
    360                 int flow2 = min_cost_flow(S, T, f);
    361                 v2.clear();
    362                 for(int u = 1; u <= n; u++)
    363                 {
    364                     if(id[u] != i) continue;
    365                     if(cl[u] == nc[u] || !cl[u]) continue;
    366                     for(int j = h[u]; j >= 0; j = e[j].pre)
    367                         if(e[j].to != S && !e[j].cap) v2.push_back(pii(u, e[j].to));
    368                 }
    369 
    370                 ans += flow2;
    371                 int sz = v2.size();
    372                 for(int j = 0; j < sz; j++)
    373                 {
    374                     int u = v2[j].first, v = v2[j].second;
    375                     path.clear(), get_path(u, v);
    376                     int sp = path.size(), last = 0;
    377                     for(int k = 0; k < sp; k++)
    378                     if(cl[path[k].first] != cl[path[k].second])
    379                     {
    380                         for(int r = k; r >= last; r--)
    381                         {
    382                             tmp.push_back(path[r]);
    383                             swap(cl[path[r].first], cl[path[r].second]);
    384                         }
    385                         last = k + 1;
    386                     }
    387                 }
    388 
    389             }
    390 
    391             else {ok = 0; break;}
    392 
    393         }
    394 
    395 
    396         if(!ok) puts("-1");
    397         else
    398         {
    399             printf("%d
    ", ans);
    400             int sz = tmp.size();
    401             for(int i = 0; i < sz; i++) printf("%d %d
    ", tmp[i].first, tmp[i].second);
    402         }
    403 
    404     }
    405     return 0;
    406 }
    Aguin

    1008 Helter Skelter

    据说可行域是连续区间而且一维随另一维单调不减而且转折点都是01分界点哦。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <algorithm>
     5 using namespace std;
     6 typedef pair<int, int> pii;
     7 const int INF = 2e9;
     8 const int maxn = 1e6 + 10;
     9 int x[1111];
    10 vector<pii> z, o;
    11 pii stz[maxn], sto[maxn];
    12 char ans[maxn];
    13 
    14 int main(void)
    15 {
    16     int T;
    17     scanf("%d", &T);
    18     while(T--)
    19     {
    20         int n, m;
    21         scanf("%d %d", &n, &m);
    22         for(int i = 1; i <= n; i++) scanf("%d", x + i);
    23 
    24         z.clear(), o.clear();
    25         for(int i = 1; i <= n; i++)
    26         {
    27             int c0 = 0, c1 = 0;
    28             for(int j = i; j <= n; j++)
    29             {
    30                 if(j % 2) c0 += x[j];
    31                 else c1 += x[j];
    32                 if(j % 2 == 1 && i % 2 == 1) z.push_back(pii(c0, c1));
    33                 if(j % 2 == 0 && i % 2 == 0) o.push_back(pii(c0, c1));
    34             }
    35         }
    36 
    37         sort(z.begin(), z.end());
    38         sort(o.begin(), o.end());
    39 
    40         int sz = z.size(), so = o.size();
    41         int pz = 0, po = 0;
    42 
    43         for(int i = 0; i < sz; i++)
    44         {
    45             if(i && z[i].first == z[i-1].first) continue;
    46             while(pz && stz[pz].second >= z[i].second) pz--;
    47             stz[++pz] = z[i];
    48         }
    49 
    50         for(int i = 0; i < so; i++)
    51         {
    52             if(i < so - 1 && o[i].first == o[i+1].first) continue;
    53             if(!po || o[i].second > sto[po].second) sto[++po] = o[i];
    54         }
    55 
    56         for(int i = 0; i < m; i++)
    57         {
    58             int a, b;
    59             scanf("%d %d", &a, &b);
    60             int l = lower_bound(stz + 1, stz + 1 + pz, pii(a, 0)) - stz;
    61             int u = lower_bound(sto + 1, sto + 1 + po, pii(a, INF)) - sto - 1;
    62             if(l < pz + 1 && b >= stz[l].second && b <= sto[u].second) ans[i] = '1';
    63             else ans[i] = '0';
    64         }
    65         ans[m] = 0;
    66         puts(ans);
    67     }
    68     return 0;
    69 }
    Aguin

    1009 It's All In The Mind

    1010 Join The Future

    1011 Keep On Movin

    1012 La Vie en rose

    1013 Memento Mori

  • 相关阅读:
    OA
    Asp.net 将js文件打包进dll 方法
    ASP.NET编程中的十大技巧
    jquery 1.2.6 中文注释解析
    javascript 构造函数和方法
    asp.net命名空间
    .ascx和网页.aspx之间的交互方式
    windows 2003局域网共享设置
    javascript高级编程
    程序员需要具备的基本技能
  • 原文地址:https://www.cnblogs.com/Aguin/p/5693233.html
Copyright © 2011-2022 走看看