zoukankan      html  css  js  c++  java
  • ACM-ICPC 2018 徐州赛区网络预赛 Solution

    A. Hard to prepare

    题意:有n个客人做成一圈,有$2^k$种面具,对于每种面具有一种面具不能使相邻的两个人戴,共有多少种做法。

    思路: 把题意转化成相邻的人不能带同种面具。总数为$(2^k)^n$,减去一对相邻的客人戴同种面具$(2^k)^{(n-1)}*C(n,1)$,其中重复了两对相邻的客人戴同种面具$(2^k)^{(n-2)}*C(n,2)$,依次容斥。

    最后所有人都戴同种面具的情况额外考虑,当n是奇数时,n-1对客人相同即所有人相同。n为偶数时,n-1对客人相同时用公式有重复的一轮,所以要加上。

    设t=2^k

    $sum_{i = 0}^{i = n - 1} C_n^i cdot t^{n - 1} * (-1)^i$ (n 是奇数)

    $sum_{i = 0}^{i = n - 1} C_n^i cdot t^{n - 1} * (-1)^i + t$ (n 是偶数)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 1000010
     6 
     7 const ll MOD = (ll)1e9 + 7;
     8 
     9 int t, n, k; 
    10 ll inv[N];
    11 ll Bit[N];
    12 ll Bitt[N];
    13 
    14 inline void Init()
    15 {
    16     inv[1] = 1;
    17     for (int i = 2; i < N; ++i) inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;
    18     Bit[0] = 1;
    19     for (int i = 1; i < N; ++i) Bit[i] = (Bit[i - 1] * 2) % MOD;
    20 }
    21 
    22 inline void init()
    23 {
    24     Bitt[0] = 1; ll tmp = Bit[k];
    25     for (int i = 1; i <= n; ++i) Bitt[i] = (Bitt[i - 1] * tmp) % MOD; 
    26 }
    27 
    28 inline void Run()
    29 {
    30     scanf("%d", &t); Init();
    31     while (t--)
    32     {
    33         scanf("%d%d", &n, &k); 
    34         if (k == 1)
    35         {
    36             puts("2"); 
    37             continue;
    38         }
    39         else if (n == 1)
    40         {
    41             printf("%lld
    ",Bit[k]); 
    42             continue;
    43         }
    44         init();
    45         ll res = 0;
    46         ll C = 1;
    47         for (int i = 0; i < n; ++i)
    48         {
    49             res = (res + (C * Bitt[n - i] % MOD * ((i & 1) ? -1 : 1) + MOD) % MOD) % MOD;
    50             C = C * (n - i) % MOD * inv[i + 1] % MOD;
    51         }
    52         res = (res + (Bit[k] * ((n & 1) ? 0 : 1)) % MOD + MOD) % MOD; 
    53         printf("%lld
    ", res);
    54     }
    55 }
    56 
    57 int main()
    58 {
    59     #ifdef LOCAL  
    60         freopen("Test.in", "r", stdin);
    61     #endif  
    62 
    63     Run();
    64     return 0;
    65 }
    View Code

    B. BE, GE or NE

    题意:每一轮有三种操作, 加上a 减去b 或者 取负 当且仅当 a, b, c 不为0时,对应的操作有效,给出一个上界和一个下界 大于等于上界就是 Good Ending 小于等于下界 就是 Bad Ending 否则就是 Normal Ending  两个人轮流操作,第一个人想要Good Ending 第二个人想要 Bad Ending  两个人操作最优,求最后的结局

    思路:dp[i][j] 表示 第几轮 数字是多少的时候 ,记忆化爆搜 因为数字在$[-100, 100]$

      1 #include <bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 typedef long long ll;
      6 
      7 const int MOD = (int)1e9 + 7;
      8 const int INF = 0x3f3f3f3f;
      9 const ll INFLL = 0x3f3f3f3f3f3f3f3f;
     10 const int maxn = (int)1e3 + 10;
     11 
     12 struct node {
     13     int a, b, c;
     14     inline node() {}
     15     inline node(int a, int b, int c) :a(a), b(b), c(c) {}
     16 }arr[maxn];
     17 
     18 int n, m, l, k;
     19 int type[maxn][maxn];//1 good  0 normal  -1 bad
     20 int vis[maxn][maxn];
     21 
     22 inline void Init()
     23 {
     24     memset(vis, 0, sizeof vis);
     25     memset(type, 0, sizeof type);
     26 }
     27 
     28 inline int DFS(int idx, int state)
     29 {
     30     if (idx > n)
     31     {
     32         if (state <= l) return -1;
     33         else if (state >= k) return 1;
     34         else return 0;
     35     }
     36     if (vis[idx][state]) return type[idx][state];
     37     vis[idx][state] = 1;
     38     int res = 0;
     39     //a
     40     int A = 2, B = 2, C = 2;
     41     if (arr[idx].a)
     42     {
     43         A = DFS(idx + 1, min(100, state + arr[idx].a));
     44     }
     45     //b
     46     if (arr[idx].b)
     47     {
     48         B = DFS(idx + 1, max(-100, state - arr[idx].b));
     49     }
     50     //c
     51     if (arr[idx].c)
     52     {
     53         C = DFS(idx + 1, max(-100, min(100, state * -arr[idx].c)));
     54     }
     55     if ((A == 1 || A == 2)&& (B == 1 || B == 2) && (C == 1 || C == 2) && (idx & 1) == 0)
     56     {
     57         type[idx][state] = 1;
     58         return 1;
     59     }
     60     else if ((A == -1 || A == 2) && (B == -1 || B == 2) && (C == -1 || C == 2) && (idx & 1) == 1)
     61     {
     62         type[idx][state] = -1;
     63         return -1;
     64     }
     65     else if ((A == 1 || B == 1 || C == 1) && (idx & 1) == 1)
     66     {
     67         type[idx][state] = 1;
     68         return 1;
     69     }
     70     else if ((A == -1 || B == -1 || C == -1) && (idx & 1) == 0)
     71     {
     72         type[idx][state] = -1;
     73         return -1;
     74     }
     75     else
     76     {
     77         type[idx][state] = 0;
     78         return 0;
     79     }
     80 }
     81 
     82 inline void RUN()
     83 {
     84     while (~scanf("%d %d %d %d", &n, &m, &k, &l))
     85     {
     86         Init(); 
     87         for (int i = 1; i <= n; ++i)
     88         {
     89             scanf("%d %d %d", &arr[i].a, &arr[i].b, &arr[i].c);
     90         }
     91         int ans = DFS(1, m);
     92         if (ans == 1)
     93         {
     94             puts("Good Ending");
     95         }
     96         else if (ans == -1)
     97         {
     98             puts("Bad Ending");
     99         }
    100         else
    101         {
    102             puts("Normal Ending");
    103         }
    104     }
    105 }
    106 
    107 int main()
    108 {
    109 #ifdef LOCAL_JUDGE
    110     freopen("Text.txt", "r", stdin);
    111 #endif // LOCAL_JUDGE
    112 
    113     RUN();
    114 
    115 #ifdef LOCAL_JUDGE
    116     fclose(stdin);
    117 #endif // LOCAL_JUDGE
    118 }
    View Code

    C. Cacti Lottery

    留坑。

    D. Easy Math

    留坑。

    E. End Fantasy VIX

    留坑。

    F. Features Track

    水。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 100010
     5 #define ll long long
     6 
     7 typedef pair <ll, ll> pii;
     8 
     9 int t, n, tot;
    10 ll ans, x, y;
    11 map <pii, pii> mp; 
    12 
    13 inline void Run()
    14 {
    15     scanf("%d", &t);
    16     while (t--)
    17     {
    18         scanf("%d", &n); mp.clear(); ans = 0;
    19         for (int i = 1; i <= n; ++i)
    20         {
    21             scanf("%d", &tot);
    22             for (int j = 1; j <= tot; ++j)
    23             {
    24                 scanf("%lld%lld", &x, &y);
    25                 if (mp[pii(x, y)].second == i - 1) ++mp[pii(x, y)].first;
    26                 else if (mp[pii(x, y)].second == i) continue;
    27                 else mp[pii(x, y)].first = 1;
    28                 ans = max(ans, mp[pii(x, y)].first);
    29                 mp[pii(x, y)].second = i;
    30             }
    31         }
    32         printf("%lld
    ", ans);
    33     }
    34 }
    35 
    36 int main()
    37 {
    38     #ifdef LOCAL  
    39         freopen("Test.in", "r", stdin);
    40     #endif  
    41 
    42     Run();
    43     return 0;
    44 }
    View Code

    G. Trace

    题意:每次给出一个点,然后就会形成两条线,如果后面的矩形覆盖了前面的边,那么这条边就消失了, 最后求剩下的边是多少

    思路:分别处理x轴,y轴,然后排序,然后扫过去,每次加上自己的边长以及减去标号比自己小的并且长度比自己高的个数乘自己的边长

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define N 50010
      5 #define ll long long
      6 
      7 int n;
      8 
      9 struct node
     10 {
     11     int l, r;
     12     int lazy, sum;
     13     inline node() {}
     14     inline node(int _l, int _r)
     15     {
     16         l = _l, r = _r;
     17         lazy = -1;
     18         sum = 0;
     19     }
     20 }tree[N << 2];
     21 
     22 inline void pushup(int id)
     23 {
     24     tree[id].sum = tree[id << 1].sum + tree[id << 1 | 1].sum;
     25 }
     26 
     27 inline void pushdown(int id)
     28 {
     29     if (tree[id].l >= tree[id].r) return;
     30     if (~tree[id].lazy) 
     31     {
     32         int lazy = tree[id].lazy; tree[id].lazy = -1;
     33         tree[id << 1].lazy = tree[id << 1 | 1].lazy = lazy;
     34         tree[id << 1].sum = tree[id << 1 | 1].sum = 0;
     35     }
     36 }
     37 
     38 inline void build(int id, int l, int r) 
     39 {
     40     tree[id] = node(l, r);
     41     if (l == r) return;
     42     int mid = (l + r) >> 1;
     43     build(id << 1, l, mid);
     44     build(id << 1 | 1, mid + 1, r);
     45 }
     46 
     47 inline void update(int id, int l, int r, int val)
     48 {
     49     if (tree[id].l >= l && tree[id].r <= r)
     50     {
     51         tree[id].sum = val; 
     52         tree[id].lazy = val;
     53         return;
     54     }
     55     pushdown(id);
     56     int mid = (tree[id].l + tree[id].r) >> 1;
     57     if (l <= mid) update(id << 1, l, r, val); 
     58     if (r > mid) update(id << 1 | 1, l, r, val);
     59     pushup(id);
     60 }
     61 
     62 inline int query(int id, int l, int r)
     63 {
     64     if (tree[id].l >= l && tree[id].r <= r) return tree[id].sum;
     65     pushdown(id);
     66     int mid = (tree[id].l + tree[id].r) >> 1;
     67     int res = 0;
     68     if (l <= mid) res += query(id << 1, l, r);
     69     if (r > mid) res += query(id << 1 | 1, l, r);
     70     return res;
     71 }
     72 
     73 struct DT
     74 {
     75     int pos;
     76     ll x, y;
     77     inline void scan(int _pos)
     78     {
     79         pos = _pos;
     80         scanf("%lld%lld", &x, &y);
     81     }
     82 }arr[N];
     83 
     84 inline bool cmp1(DT a, DT b)
     85 {
     86     return a.x < b.x;
     87 }
     88 
     89 inline bool cmp2(DT a, DT b)
     90 {
     91     return a.y < b.y;
     92 }
     93 
     94 inline void Run()
     95 {
     96     while (scanf("%d", &n) != EOF)
     97     {
     98         for (int i = 1; i <= n; ++i) arr[i].scan(i);
     99         build(1, 1, n); 
    100         sort(arr + 1, arr + 1 + n, cmp1);
    101         ll res = 0;
    102         for (int i = 1; i <= n; ++i)
    103         {
    104             res += arr[i].y;
    105             int pos = query(1, 1, arr[i].pos);
    106             res -= arr[i].y * pos; 
    107             update(1, 1, arr[i].pos, 0);
    108             update(1, arr[i].pos, arr[i].pos, 1);
    109         }
    110         sort(arr + 1, arr + 1 + n, cmp2);
    111         update(1, 1, n, 0); 
    112         for (int i = 1; i <= n; ++i)
    113         {
    114             res += arr[i].x;
    115             int pos = query(1, 1, arr[i].pos);
    116             res -= arr[i].x * pos;
    117             update(1, 1, arr[i].pos, 0);
    118             update(1, arr[i].pos, arr[i].pos, 1);
    119         }
    120         printf("%lld
    ", res);
    121     }
    122 }
    123 
    124 int main()
    125 {
    126     #ifdef LOCAL  
    127         freopen("Test.in", "r", stdin);
    128     #endif  
    129 
    130     Run();
    131     return 0;
    132 }
    View Code

    栈维护:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 50010
     5 #define ll long long
     6 
     7 int n;
     8 
     9 struct node
    10 {
    11     int pos; 
    12     ll x, y;
    13     inline void scan(int _pos)
    14     {
    15         pos = _pos;
    16         scanf("%lld%lld", &x, &y);
    17     }
    18 }arr[N];
    19 
    20 inline bool cmp1(node a, node b)
    21 {
    22     return a.x < b.x;
    23 }
    24 
    25 inline bool cmp2(node a, node b)
    26 {
    27     return a.y < b.y;
    28 }
    29 
    30 inline void Run()
    31 {
    32     while (scanf("%d", &n) != EOF)
    33     {
    34         for (int i = 1; i <= n; ++i) arr[i].scan(i);
    35         sort(arr + 1, arr + 1 + n, cmp1); 
    36         ll res = 0;
    37         stack<int>s;
    38         for (int i = 1; i <= n; ++i)
    39         {
    40             res += arr[i].y;
    41             int cnt = 0;
    42             while (!s.empty() && s.top() < arr[i].pos)
    43             {
    44                 cnt++;
    45                 s.pop();
    46             }
    47             res -= cnt * arr[i].y;
    48             s.push(arr[i].pos);
    49         }
    50         while (!s.empty())
    51         {
    52             s.pop();
    53         }
    54         sort(arr + 1, arr + 1 + n, cmp2);
    55         for (int i = 1; i <= n; ++i)
    56         {
    57             res += arr[i].x;
    58             int cnt = 0;
    59             while (!s.empty() && s.top() < arr[i].pos)
    60             {
    61                 cnt++;
    62                 s.pop();
    63             }
    64             res -= cnt * arr[i].x;
    65             s.push(arr[i].pos);
    66         }
    67         printf("%lld
    ", res);
    68     }
    69 }
    70 
    71 int main()
    72 {
    73     #ifdef LOCAL_JUDGE
    74         freopen("Text.txt", "r", stdin);
    75     #endif  
    76 
    77     Run();
    78     return 0;
    79 }
    View Code

    H. Ryuji doesn't want to study

    题意:两个操作,第一种是查询$[L, R]$ 区间内 $a[L] * len + a[L + 1] * (len - 1) + ... + a[R] * 1$

    第二种是改变一个数

    思路:线段树,记录两个值,一个是sum,另一个是 $a[L] * len + a[L + 1] * (len - 1) + ... + a[R] * 1$

    考虑合并的时候 显然两个区间合并,相当于左区间的长度增加了右区间的长度,那么只需要多加上左区间的sum * 右区间长度

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define N 100010
      5 #define ll long long
      6 
      7 int n, q;
      8 ll arr[N];
      9 
     10 struct node
     11 {
     12     int l, r;
     13     ll sum1, sum2;
     14     inline node() {}
     15     inline node(int l, int r, ll sum1, ll sum2) : l(l), r(r), sum1(sum1), sum2(sum2) {}
     16 }tree[N << 2];
     17 
     18 inline void pushup(int id)
     19 {
     20     tree[id].sum1 = tree[id << 1].sum1 + tree[id << 1 | 1].sum1;
     21     tree[id].sum2 = tree[id << 1 | 1].sum2 + tree[id << 1].sum2 + tree[id << 1].sum1 * (tree[id << 1 | 1].r - tree[id << 1 | 1].l + 1);
     22 }
     23 
     24 inline void build(int id, int l, int r)
     25 {
     26     tree[id] = node(l, r, 0, 0);
     27     if (l == r)
     28     {
     29         tree[id].sum1 = arr[tree[id].l];
     30         tree[id].sum2 = arr[tree[id].l];
     31         return;
     32     }
     33     int mid = (l + r) >> 1;
     34     build(id << 1, l, mid);
     35     build(id << 1 | 1, mid + 1, r); 
     36     pushup(id);
     37 }
     38 
     39 inline void update(int id, int pos, ll val)
     40 {
     41     if (tree[id].l == tree[id].r)
     42     {
     43         tree[id].sum1 = val;
     44         tree[id].sum2 = val;
     45         return;
     46     }
     47     int mid = (tree[id].l + tree[id].r) >> 1;
     48     if (pos <= mid) update(id << 1, pos, val);
     49     else update(id << 1 | 1, pos, val);
     50     pushup(id);
     51 }
     52 
     53 ll anssum;
     54 
     55 inline void query(int id, int l, int r)
     56 {
     57     if (tree[id].l >= l && tree[id].r <= r)
     58     {
     59         anssum += tree[id].sum2 + tree[id].sum1 * (r - tree[id].r);
     60         return;
     61     }
     62     int mid = (tree[id].l + tree[id].r) >> 1;
     63     if (l <= mid) query(id << 1, l, r);
     64     if (r > mid) query(id << 1 | 1, l, r);
     65 }
     66 
     67 inline void Run()
     68 {
     69     while (scanf("%d%d", &n, &q) != EOF)
     70     {
     71         for (int i = 1; i <= n; ++i) scanf("%lld", arr + i);
     72         build(1, 1, n);
     73         int op, a, b; ll v;
     74         for (int i = 1; i <= q; ++i)
     75         {
     76             scanf("%d", &op);
     77             if (op == 1)
     78             {
     79                 scanf("%d%d", &a, &b);
     80                 anssum = 0; query(1, a, b);
     81                 printf("%lld
    ", anssum);
     82             }
     83             else
     84             {
     85                 scanf("%d%lld", &a, &v);
     86                 update(1, a, v);
     87             }
     88         }
     89     }
     90 }
     91 
     92 int main()
     93 {
     94     #ifdef LOCAL  
     95         freopen("Test.in", "r", stdin);
     96     #endif  
     97 
     98     Run();
     99     return 0;
    100 }
    View Code

    I. Characters with Hash

    水。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 const int MOD = (int)1e9 + 7;
     8 const int INF = 0x3f3f3f3f;
     9 const ll INFLL = 0x3f3f3f3f3f3f3f3f;
    10 const int maxn = (int)1e6 + 10;
    11 
    12 int n;
    13 char s[10];
    14 char str[maxn];
    15 
    16 int arr[maxn];
    17 
    18 inline void RUN()
    19 {
    20     int t;
    21     scanf("%d", &t);
    22     while (t--)
    23     {
    24         scanf("%d", &n);
    25         scanf("%s", s);
    26         scanf("%s", str);
    27         int len = strlen(str);
    28         for (int i = 0; i < len; ++i)
    29         {
    30             arr[i] = abs(str[i] - s[0]);
    31         }
    32         int ans = 2 * len;
    33         for (int i = 0; i < len; ++i)
    34         {
    35             if (arr[i] == 0)
    36             {
    37                 ans -= 2;
    38             }
    39             else if (arr[i] < 10)
    40             {
    41                 ans -= 1;
    42                 break;
    43             }
    44             else
    45             {
    46                 break;
    47             }
    48         }
    49         if (ans == 0) ans = 1;
    50         printf("%d
    ", ans);
    51     }
    52 }
    53 
    54 int main()
    55 {
    56 #ifdef LOCAL_JUDGE
    57     freopen("Text.txt", "r", stdin);
    58 #endif // LOCAL_JUDGE
    59 
    60     RUN();
    61 
    62 #ifdef LOCAL_JUDGE
    63     fclose(stdin);
    64 #endif // LOCAL_JUDGE
    65 }
    View Code

    J. Maze Designer
    题意:有一个$n * m$ 的迷宫,我们要建一些边使得其构成迷宫,要花费最小,然后给出两个点求最短距离

    思路:花费最小,其实就是求最大生成树,那么剩下的边则为迷宫

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define N 300010
      5 #define ll long long
      6 
      7 struct Edge
      8 {
      9     int to, nx; ll w; 
     10     inline Edge() {}
     11     inline Edge(int to, int nx, ll w) : to(to), nx(nx), w(w) {}
     12     inline bool operator < (const Edge &r) const
     13     {
     14         return w > r.w;  
     15     }
     16 }edge[N << 1], ed[N << 1]; 
     17 
     18 int n, m, q;
     19 int head[N], pos, cnt, tot;
     20 int pre[N], F[N << 1], P[N], rmq[N << 1];
     21 ll dist[N];  
     22 
     23 inline void Init()
     24 {
     25     memset(head, -1, sizeof head); pos = 0; cnt = 0; dist[1] = 0; tot = 0;
     26     for (int i = 1; i <= n * m; ++i) pre[i] = i;
     27 }
     28 
     29 inline void addedge(int u, int v, ll w) 
     30 {
     31     edge[++pos] = Edge(v, head[u], w); head[u] = pos;
     32 }
     33 
     34 struct ST
     35 {
     36     int mm[N << 1];
     37     int dp[N << 1][20];
     38     inline void init(int n)
     39     {
     40         mm[0] = -1;
     41         for (int i = 1; i <= n; ++i)
     42         {
     43             mm[i] = ((i & (i - 1)) == 0) ? mm[i - 1] + 1 : mm[i - 1];
     44             dp[i][0] = i;
     45         }
     46         for (int j = 1; j <= mm[n]; ++j)
     47         {
     48             for (int i = 1; i + (1 << j) - 1 <= n; ++i)
     49             {
     50                 dp[i][j] = rmq[dp[i][j - 1]] < rmq[dp[i + (1 << (j - 1))][j - 1]] ? dp[i][j - 1] : dp[i + (1 << (j - 1))][j - 1];
     51             }
     52         }
     53     }
     54     inline int query(int a, int b)
     55     {
     56         if (a > b) swap(a, b);
     57         int k = mm[b - a + 1];
     58         return rmq[dp[a][k]] <= rmq[dp[b - (1 << k) + 1][k]] ? dp[a][k] : dp[b - (1 << k) + 1][k];
     59     }
     60 }st;
     61 
     62 inline void DFS(int u, int pre, int dep)
     63 {
     64     F[++tot] = u;
     65     rmq[tot] = dep;
     66     P[u] = tot;
     67     for (int it = head[u]; ~it; it = edge[it].nx)
     68     {
     69         int v = edge[it].to;
     70         if (v == pre) continue;
     71         dist[v] = dist[u] + 1;
     72         DFS(v, u, dep + 1);
     73         F[++tot] = u;
     74         rmq[tot] = dep;
     75     }
     76 }
     77 
     78 inline void Lca_Init(int root, int node_num)
     79 {
     80     DFS(root, root, 0);
     81     st.init(2 * node_num - 1);
     82 }
     83 
     84 inline int query_lca(int u, int v)
     85 {
     86     return F[st.query(P[u], P[v])]; 
     87 }
     88 
     89 inline int find(int x)
     90 {
     91     if (pre[x] != x)
     92         pre[x] = find(pre[x]); 
     93     return pre[x];
     94 }
     95 
     96 inline void join(int x, int y)
     97 {
     98     int fx = find(x), fy = find(y);
     99     if (fx != fy)
    100         pre[fx] = fy;
    101 }
    102 
    103 inline void Kruskal()
    104 {
    105     sort(ed + 1, ed + 1 + cnt); 
    106     int Count = 1;
    107     for (int i = 1; i <= cnt; ++i)
    108     {
    109         int u = ed[i].to, v = ed[i].nx;
    110         if (find(u) == find(v)) continue; 
    111         addedge(u, v, ed[i].w); addedge(v, u, ed[i].w);
    112         join(u, v);
    113         ++Count;
    114         if (Count == n * m)    return;   
    115     }
    116     return;
    117 }
    118 
    119 inline void Run()
    120 {
    121     while (scanf("%d%d", &n, &m) != EOF)
    122     {
    123         Init();
    124         char dir; ll w; int u, v;
    125         for (int i = 1; i <= n; ++i)
    126         {
    127             for (int j = 1; j <= m; ++j)
    128             {
    129                 for (int k = 0; k < 2; ++k)
    130                 {
    131                     scanf(" %c %lld", &dir, &w);
    132                     u = (i - 1) * n + j;
    133                     if (dir == 'X') continue; 
    134                     if (dir == 'D') v = i * n + j;
    135                     else if (dir == 'R') v = (i - 1) * n + j + 1;
    136                     ed[++cnt] = Edge(u, v, w); 
    137                 } 
    138             }
    139         }
    140         Kruskal(); Lca_Init(1, n * m); 
    141         int x[2], y[2];  
    142         scanf("%d", &q);
    143         for (int i = 1; i <= q; ++i)
    144         {
    145             scanf("%d%d%d%d", &x[0], &y[0], &x[1], &y[1]);
    146             u = (x[0] - 1) * n + y[0], v = (x[1] - 1) * n + y[1];
    147             int lca = query_lca(u, v);
    148             //printf("%d %d %d
    ", u, v, lca);
    149             printf("%lld
    ", dist[u] + dist[v] - 2 * dist[lca]); 
    150         }
    151         
    152     }
    153 }
    154 
    155 int main()
    156 {
    157     #ifdef LOCAL  
    158         freopen("Test.in", "r", stdin);
    159     #endif   
    160 
    161     Run();
    162     return 0;
    163 }  
    View Code

    K. Morgana Net

    留坑。

  • 相关阅读:
    HDU4507 吉哥系列故事――恨7不成妻(数位dp)
    UCF Local Programming Contest 2017 G题(dp)
    ICPC Latin American Regional Contests 2019 I题
    UCF Local Programming Contest 2017 H题(区间dp)
    HDU2089 不要62
    AcWing1084 数字游戏II(数位dp)
    UCF Local Programming Contest 2017 F题(最短路)
    Google Code Jam 2019 Round 1A Pylons(爆搜+贪心)
    AcWing1083 Windy数(数位dp)
    Vue
  • 原文地址:https://www.cnblogs.com/Dup4/p/9614543.html
Copyright © 2011-2022 走看看