1. 程式人生 > >2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror) Partial Solution

2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror) Partial Solution

從這裡開始

瞎扯

  又來打比賽了,發現自己菜得不行。

  果然我是標準的普及組選手。(這個隊名是啥意思?我也不知道,因為不知道取啥隊名,就隨機在鍵盤上敲Emmm)

  這次隊友很給力,把我不會的模擬和貪心全切掉了,並且每次翻譯了正確的題意(我英語真垃圾)。(上次UESTC ACM Final的隊友讓我很絕望,既不會做題又給我翻譯假題面)

  然後我把剩下的送分題都切掉了。

  於是被碾壓了:

  開始通讀全題(提供pdf真良心,避免網絡卡耽誤時間),我覺得很絕望,尤其是那個B,讀得我很絕望,直接扔翻譯裡都棄了。

  之後並不知道怎麼做題,然後隨機一道題,發現是水題是一道水題就直接切掉了。

  之後就開始看榜,那個題通過的隊多就做哪個。

  佬表示這個不是正確的做法,正確的做法是每個人隨機若干道題,先自己去做,不會的話然後扔給隊友。

  掛掉的話也可以扔隊友。

  但是我和我隊友都挺菜的,這麼搞可能完蛋了。

  下來發現B,J都是送分題。

Problem A Find a Number

題目大意

  問最小的滿足各位數字之和為$s$並且能被$d$整除的正整數。

  首先用bfs確定它的位數,每個狀態記錄通過儘量小的轉移邊轉移的前驅。

  然後做完了。

Code

 1 /**
 2  * Codeforces
 3  * Problem#1070A
 4  * Accepted
 5  * Time: 108ms
 6  * Memory: 24800k
 7  * Author: yyf
 8  */
 9 #include <iostream>
10 #include <cstdlib>
11 #include <cstring>
12 #include <cstdio>
13 #include <queue>
14 using namespace std;
15 typedef bool boolean;
16 
17 const int N = 5005, D = 505;
18 #define pii pair<int, int>
19 #define fi first
20 #define sc second
21 
22 int d, s;
23 int f[N][D];
24 char lst[N][D];
25 int lstr[N][D];
26 boolean vis[N][D];
27 
28 pii trans(int s, int r, int dig) {
29     return pii(s + dig, (r * 10 + dig) % d);
30 }
31 
32 inline void init() {
33     scanf("%d%d", &d, &s);
34 }
35 
36 queue<pii> que;
37 boolean bfs() {
38     que.push(pii(0, 0));
39     memset(f, 0x3f, sizeof(f));
40     f[0][0] = 0, vis[0][0] = true;
41     while (!que.empty()) {
42         pii e = que.front();
43         que.pop();
44 
45         for (int i = 0; i <= 9; i++) {
46             pii eu = trans(e.fi, e.sc, i);
47             if (eu.fi > s)
48                 break;
49             if (vis[eu.fi][eu.sc])
50                 continue;
51             vis[eu.fi][eu.sc] = true;
52             lst[eu.fi][eu.sc] = i + '0';
53             lstr[eu.fi][eu.sc] = e.sc;
54             f[eu.fi][eu.sc] = f[e.fi][e.sc] + 1;
55             que.push(eu);
56         }
57     }
58     return vis[s][0];
59 }
60 
61 void print(int s, int r) {
62     if (!s && !r)
63         return ;
64     int nr = lstr[s][r];
65     print(s - lst[s][r] + '0', nr);
66     putchar(lst[s][r]);
67 }
68 
69 
70 inline void solve() {
71     if (bfs()) {
72         print(s, 0);
73     } else
74         puts("-1");
75 }
76 
77 int main() {
78     init();
79     solve();
80     return 0;
81 }
Problem A

Problem B Berkomnadzor

題目大意

  給定一個IPv4白名單和黑名單,要求用最少的IPv4碼給出一個包含所有黑名單中的地址但不包含任何一個白名單裡的地址。

  先判掉無解的情況。

  剩下直接分治。

Code

  1 /**
  2  * Codeforces
  3  * Problem#1070B
  4  * Accepted
  5  * Time: 530ms
  6  * Memory: 52800k
  7  */
  8 #include <bits/stdc++.h>
  9 using namespace std;
 10 typedef bool boolean;
 11 
 12 #define ull unsigned long long
 13 #define pii pair<int, int>
 14 #define ll long long
 15 #define ui unsigned
 16 #define sc second
 17 #define fi first
 18 
 19 const signed ll llf = (signed ll) (~0ull >> 1);
 20 const signed int inf = (signed) (~0u >> 1);
 21 
 22 template <typename T>
 23 T __abs(T x) {
 24     return (x < 0) ? (-x) : (x);
 25 }
 26 
 27 template <typename T>
 28 void pfill(T* pst, const T* ped, T val) {
 29     for ( ; pst != ped; *(pst++) = val);
 30 }
 31 
 32 template <typename T>
 33 void pcopy(T* pst, const T* ped, T* pv) {
 34     for ( ; pst != ped; *(pst++) = *(pv++));
 35 }
 36 
 37 #define digit(_x) ((_x) >= '0' && (_x) <= '9')
 38 
 39 template <typename T>
 40 char* read(char* s, T& u) {
 41     for ( ; *s && !digit(*s); s++);
 42     if (!*s)
 43         return NULL;
 44     for (u = *s - '0'; ++s, digit(*s); u = u * 10 + *s - '0');
 45     return s;
 46 }
 47 
 48 const int N = 2e5 + 5;
 49 
 50 typedef class Segment {
 51     public:
 52         ui l, r;
 53         ui sgn;
 54 
 55         Segment() {    }
 56         Segment(ui l, ui r, ui sgn):l(l), r(r), sgn(sgn) {    }
 57 
 58         boolean operator < (Segment b) const { 
 59             if (l ^ b.l)
 60                 return l < b.l;
 61             return r < b.r;
 62         }
 63 
 64         boolean intersect(Segment b) {
 65             return !(b.r < l || b.l > r);
 66         }
 67 }Segment;
 68 
 69 int n;
 70 char buf[100];
 71 
 72 Segment read() {
 73     ui l, r, x;
 74     scanf("%s", buf);
 75     ui sgn = (buf[0] == '+');
 76     char* str = buf + 1;
 77     str = read(str, l);
 78     str = read(str, x), l = l << 8 | x;
 79     str = read(str, x), l = l << 8 | x;
 80     str = read(str, x), l = l << 8 | x;
 81     if (*str == '/') {
 82         read(str, x);
 83         x = 32 - x;
 84         l >>= x, l <<= x;
 85         if (x == 32)
 86             r = ~0u;
 87         else
 88             r = l | ((1 << x) - 1);
 89         return Segment(l, r, sgn);
 90     }
 91     return Segment(l, l, sgn);
 92 }
 93 
 94 int res = 0;
 95 vector<Segment> ss, rs;
 96 
 97 inline void init() {
 98     scanf("%d", &n);
 99     Segment s;
100     for (int i = 1; i <= n; i++)
101         s = read(), ss.push_back(s);
102 }
103 
104 void dividing(vector<Segment> &ss, ui l, ui r, ui bit) {
105     if (ss.empty())
106         return;
107     boolean app1 = false, app0 = false;
108     for (ui i = 0; i < ss.size(); i++)
109         app1 |= (ss[i].sgn == 1), app0 |= (ss[i].sgn == 0);
110     
111     if (!app1) {
112         rs.push_back(Segment(l, 32 - bit, 0));
113         return;
114     }
115 
116     if (!app0)
117         return;
118 
119     assert(l ^ r);
120 
121     ui mid = l + ((r - l) >> 1);
122     vector<Segment> ql, qr;
123     for (ui i = 0; i < ss.size(); i++) {
124         if (ss[i].r <= mid)
125             ql.push_back(ss[i]);
126         else if (ss[i].l > mid)
127             qr.push_back(ss[i]);
128         else {
129             ql.push_back(Segment(ss[i].l, mid, ss[i].sgn));
130             qr.push_back(Segment(mid + 1, ss[i].r, ss[i].sgn));
131         }
132     }
133     ss.clear();
134     dividing(ql, l, mid, bit - 1);
135     dividing(qr, mid + 1, r, bit - 1);
136 }
137 
138 inline void solve() {
139     sort(ss.begin(), ss.end());
140     for (ui i = 0, j; i < ss.size(); i = j)
141         for (j = i + 1; j < ss.size() && ss[j].intersect(ss[i]); j++)
142             if (ss[j].sgn ^ ss[i].sgn) {
143                 puts("-1");
144                 return;
145             }
146     dividing(ss, 0, ~0u, 32);
147     printf("%u\n", rs.size());
148     ui msk = (1 << 8) - 1;
149     for (ui i = 0, x; i < rs.size(); i++) {
150         x = rs[i].l;
151         printf("%u.%u.%u.%u/%u\n", x >> 24, x >> 16 & msk, x >> 8 & msk, x & msk, rs[i].r);
152     }
153 }
154 
155 int main() {
156     init();
157     solve();
158     return 0;
159 }
Problem B

Problem C Cloud Computing

題目大意

  一個公司每天需要$K$個CPU核心,有$m$個供應商,在第$l_i$到第$r_i$天,以每個CPU核心$p_i$的價格提供$c_i$個,如果一天買不夠,那麼必須把能夠提供的核心都購買。問最小的總花費。

  隨便拿個資料結構就過了。

Code

  1 /**
  2  * Codeforces
  3  * Problem#1070C
  4  * Accepted
  5  * Time: 249ms
  6  * Memory: 28000k
  7  * Author: yyf
  8  */
  9 #include <algorithm>
 10 #include <iostream>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <cstdio>
 14 #include <vector>
 15 using namespace std;
 16 typedef bool boolean;
 17 
 18 typedef class Opt {
 19     public:
 20         int i, p, c;
 21         int sgn;
 22 
 23         Opt(int i, int p, int c, int sgn):i(i), p(p), c(c), sgn(sgn) {    }
 24     
 25         boolean operator < (Opt b) const {
 26             return i < b.i;
 27         }
 28 }Opt;
 29 
 30 const int bzmax = 21;
 31 
 32 template <typename T>
 33 class IndexedTree {
 34     public:
 35         int s;
 36         T* ar;
 37 
 38         IndexedTree() {    }
 39         IndexedTree(int s):s(s) {
 40             ar = new T[(s + 1)];
 41             memset(ar, 0, sizeof(T) * (s + 1));
 42         }
 43 
 44         void add(int idx, T val) {
 45             for ( ; idx <= s; idx += (idx & (-idx)))
 46                 ar[idx] += val;
 47         }
 48 
 49         T query(int idx) {
 50             T rt = 0;
 51             for ( ; idx; idx -= (idx & (-idx)))
 52                 rt += ar[idx];
 53             return rt;
 54         }
 55 
 56         int kth(int k) {
 57             int rt = 0, cur = 0;
 58             for (int l = (1 << (bzmax - 1)); l; l >>= 1)
 59                 if ((rt | l) <= s && (cur + ar[rt | l]) < k)
 60                     rt |= l, cur += ar[rt];
 61             return rt + 1;
 62         }
 63 };
 64 
 65 #define ll long long
 66 
 67 const int V = 1e6 + 3;
 68 
 69 int n, K, m;
 70 IndexedTree<ll> itc;
 71 IndexedTree<ll> its;
 72 vector<Opt> vs;
 73 
 74 inline void init() {
 75     scanf("%d%d%d", &n, &K, &m);
 76     itc = IndexedTree<ll>(V);
 77     its = IndexedTree<ll>(V);
 78     for (int i = 1, l, r, c, p; i <= m; i++) {
 79         scanf("%d%d%d%d", &l, &r, &c, &p);
 80         vs.push_back(Opt(l, p, c, 1));
 81         vs.push_back(Opt(r + 1, p, c, -1));
 82     }
 83 }
 84 
 85 ll res = 0;
 86 inline void solve() {
 87     sort(vs.begin(), vs.end());
 88     int pv = 0, s = (signed) vs.size();
 89     for (int i = 1; i <= n; i++) {
 90         while (pv < s && vs[pv].i == i) {
 91             itc.add(vs[pv].p, vs[pv].c * vs[pv].sgn);
 92             its.add(vs[pv].p, vs[pv].c * 1ll * vs[pv].p * vs[pv].sgn);
 93             pv++;
 94         }
 95         ll cnt = itc.query(V);
 96         if (cnt < K) {
 97             res += its.query(V);
 98         } else {
 99             int p = itc.kth(K);
100             cnt = itc.query(p);
101             res += its.query(p) - (cnt - K) * p;
102         }
103     }
104     cout << res << endl;
105 }
106 
107 int main() {
108     init();
109     solve();
110     return 0;
111 }
Problem C

Problem D Garbage Disposal

題目大意

  每天會產生若干垃圾,每天的垃圾只能當天或者後天處理,第$n + 1$天不能留下垃圾。每次處理垃圾至多能處理$k$個單位,問最少的總處理次數。

  隨便模擬一下就過了。

Code

 1 //Author: dream_maker
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 //----------------------------------------------
 5 //typename
 6 typedef long long ll;
 7 //convenient for
 8 #define fu(a, b, c) for (int a = b; a <= c; ++a)
 9 #define fd(a, b, c) for (int a = b; a >= c; --a)
10 #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
11 //inf of different typename
12 const int INF_of_int = 1e9;
13 const ll INF_of_ll = 1e18;
14 //fast read and write
15 template <typename T>
16 void Read(T &x) {
17   bool w = 1;x = 0;
18   char c = getchar();
19   while (!isdigit(c) && c != '-') c = getchar();
20   if (c == '-') w = 0, c = getchar();
21   while (isdigit(c)) {
22     x = (x<<1) + (x<<3) + c -'0';
23     c = getchar();
24   }
25   if (!w) x = -x;
26 }
27 template <typename T>
28 void Write(T x) {
29   if (x < 0) {
30     putchar('-');
31     x = -x; 
32   }
33   if (x > 9) Write(x / 10);
34   putchar(x % 10 + '0');
35 }
36 //----------------------------------------------
37 const int N = 3e5 + 10;
38 ll a[N], n, k, ans = 0;
39 int main() {
40   Read(n), Read(k);
41   fu(i, 1, n) Read(a[i]);
42   fu(i, 1, n - 1) {
43     if (!a[i]) continue;
44     ll num = a[i] / k;
45     if (a[i] % k) ++num;
46     a[i + 1] = max(0ll, a[i + 1] - (num * k - a[i]));
47     ans += num;
48   }
49   if (a[n]) {
50     ans += a[n] / k;
51     if (a[n] % k) ++ans;
52   }
53   Write(ans);
54   return 0;
55 }
Problem D

Problem E Getting Deals Done

題目大意

  有$n$個任務和引數$m$,每個任務有一個耗時$p_i$,以及時限$t$,要求出$d$使得按照下面方式完成的任務儘量多。

  1. 按順序完成$p_i \leqslant d$的任務
  2. 每做$m$個任務需要休息與做這$m$個任務花費的時間相等的時間。

  yangkai覺得這玩意兒可以三分,於是我們成功得到了-5.

  發現有用的$d$一定時某個$p_i$,可以把$p_i$排序,按順序插進樹狀陣列。

  每次可以二分一下求出能夠完成的任務的數量。

  時間複雜度$O(n\log^{2} n)$。

  但是這個可以二分答案。

  判斷條件是是否能夠把所有可做的任務做完。

  答案只可能是它或者它加上1後的情況,

  因為再大的時候不會花更少的時間去做數量相同的任務。

  然後我的垃圾做法就被暴打了。

  然後注意幾個地方:

  1. $p$相同的任務要一起加入樹狀陣列
  2. 樹狀陣列求第$k$大特判$k = 0$。

Code

  1 /**
  2  * Codeforces
  3  * Problem#1070E
  4  * Accepted
  5  * Time: 608ms
  6  * Memory: 4700k
  7  */
  8 #include <algorithm>
  9 #include <iostream>
 10 #include <cstring>
 11 #include <cstdlib>
 12 #include <cstdio>
 13 #ifndef WIN32
 14 #define Auto "%lld"
 15 #else
 16 #define Auto "%I64d"
 17 #endif
 18 using namespace std;
 19 typedef bool boolean;
 20 #define ll long long
 21 
 22 template <typename T>
 23 class IndexedTree {
 24     public:
 25         int s;
 26         T* ar;
 27         
 28         IndexedTree() {    }
 29         IndexedTree(int s):s(s) {
 30             ar = new T[(s + 1)];
 31             memset(ar, 0, sizeof(T) * (s + 1));
 32         }
 33 
 34         void add(int idx, T val) {
 35             for ( ; idx <= s; idx += (idx & (-idx)))
 36                 ar[idx] += val;
 37         }
 38 
 39         T query(int idx) {
 40             T rt = 0;
 41             for ( ; idx; idx -= (idx & (-idx)))
 42                 rt += ar[idx];
 43             return rt;
 44         }
 45 
 46         int kth(int k) {
 47             if (!k)
 48                 return 0;
 49             int rt = 0, cur = 0;
 50             for (int i = (1 << 18); i; i >>= 1)
 51                 if ((rt | i) <= s && ar[rt | i] + cur < k)
 52                     rt |= i, cur += ar[rt];
 53             return rt + 1;
 54         }
 55 
 56         void clear() {
 57             s = 0;
 58             delete[] ar;
 59         }
 60 };
 61 
 62 const int N = 2e5 + 5;
 63 #define pii pair<int, int>
 64 #define fi first
 65 #define sc second
 66 
 67 int T;
 68 int n, m;
 69 ll t;
 70 IndexedTree<int> itc;
 71 IndexedTree<ll> its;
 72 int ps[N];
 73 pii ar[N];
 74 
 75 inline void init() {
 76     scanf("%d%d"Auto, &n, &m, &t);
 77     itc = IndexedTree<int>(n);
 78     its = IndexedTree<ll>(n);
 79     for (int i = 1; i <= n; i++)
 80         scanf("%d", ps + i), ar[i] = pii(ps[i], i);
 81 }
 82 
 83 int query(int i) {
 84     int l = 1, r = i, mid, k, ti;
 85     ll s = 0;
 86     while (l <= r) {
 87         mid = (l + r) >> 1;
 88         k = itc.kth(mid);
 89         s = its.query(k);
 90         ti = (mid - 1) / m * m;
 91         k = itc.kth(ti);
 92         s += its.query(k);
 93         if (s > t)
 94             r = mid - 1;
 95         else
 96             l = mid + 1;
 97     }
 98     return l - 1;
 99 }
100 
101 inline void solve() {
102     int ansc = 0, ansd = 1;
103     sort(ar + 1, ar + n + 1);
104     int i = 1, c;
105     while (i <= n) {
106         int cur = ar[i].fi;
107         while (i <= n && ar[i].fi == cur) {
108             itc.add(ar[i].sc, 1);
109             its.add(ar[i].sc, ar[i].fi);
110             i++;
111         }
112         c = query(i - 1);
113         if (c > ansc)
114             ansc = c, ansd = ar[i - 1].fi;
115     }
116     printf("%d %d\n", ansc, ansd);
117 }
118 
119 void clear() {
120     itc.clear();
121     its.clear();
122 }
123 
124 int main() {
125     scanf("%d", &T);
126     while (T--) {
127         init();
128         solve();
129         clear();
130     }
131     return 0;
132 }
Problem E

Problem F Debate

題目大意

  有$n$個觀眾,每個觀眾有一個觀點是否支援$Alice$以及支援$Bob$,和一個影響度。

  要求選出一些人使得至少有一半的人支援$Alice$和一半的人支援$Bob$,最大化他們的影響度之和。

  兩者都支援的一定全選。

  然後支援一方的配對選。

  剩下的再怎麼選都不會改變還能選多少人,直接貪。

Code

  1 //Author: dream_maker
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 //----------------------------------------------
  5 //typename
  6 typedef long long ll;
  7 //convenient for
  8 #define fu(a, b, c) for (int a = b; a <= c; ++a)
  9 #define fd(a, b, c) for (int a = b; a >= c; --a)
 10 #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
 11 //inf of different typename
 12 const int INF_of_int = 1e9;
 13 const ll INF_of_ll = 1e18;
 14 //fast read and write
 15 template <typename T>
 16 void Read(T &x) {
 17   bool w = 1;x = 0;
 18   char c = getchar();
 19   while (!isdigit(c) && c != '-') c = getchar();
 20   if (c == '-') w = 0, c = getchar();
 21   while (isdigit(c)) {
 22     x = (x<<1) + (x<<3) + c -'0';
 23     c = getchar();
 24   }
 25   if (!w) x = -x;
 26 }
 27 template <typename T>
 28 void Write(T x) {
 29   if (x < 0) {
 30     putchar('-');
 31     x = -x; 
 32   }
 33   if (x > 9) Write(x / 10);
 34   putchar(x % 10 + '0');
 35 }
 36 //----------------------------------------------
 37 deque<ll> p[4];
 38 ll n, w, ans = 0;
 39 char s[3];
 40 bool cmp(ll a, ll b) {
 41   return a > b;
 42 }
 43 int main() {
 44   Read(n);
 45   fu(i, 1, n) {
 46     scanf("%s", s);
 47     Read(w);
 48     if (s[0] == '0') {
 49       if (s[1] == '0') p[0].push_back(w);
 50       else p[1].push_back(w);
 51     } else {
 52       if (s[1] == '0') p[2].push_back(w);
 53       else p[3].push_back(w);
 54     }
 55   }
 56   fu(i, 0, 3) sort(p[i].begin(), p[i].end(), cmp);
 57   ll ans = 0, num = 0, cnt0 = 0, cnt1 = 0;
 58   fv(i, p[3]) {
 59     ans += p[3][i];
 60     num++;
 61     cnt0++, cnt1++;
 62   }
 63   while (p[1].size() && p[2].size()) {
 64     num += 2;
 65     cnt1++, cnt0++;
 66     ans += p[1].front() + p[2].front();
 67     p[1].pop_front();
 68     p[2].pop_front();
 69   }
 70   int last = cnt1 * 2 - num;
 71   while (last--) {
 72     if (!p[0].size() && !p[1].size() && !p[2].size()) break;
 73     if (p[0].size()) {
 74       bool can = 1;
 75       if (p[1].size() && p[1].front() > p[0].front()) can = 0;
 76       if (p[2].size() && p[2].front() > p[0].front()) can = 0;
 77       if (can) {
 78         ans += p[0].front();
 79         p[0].pop_front();
 80         continue;
 81       }
 82     }
 83     if (p[1].size()) {
 84       bool can = 1;
 85       if (p[0].size() && p[0].front() > p[1].front()) can = 0;
 86       if (p[2].size() && p[2].front() > p[1].front()) can = 0;
 87       if (can) {
 88         ans += p[1].front();
 89         p[1].pop_front();
 90         continue;
 91       }
 92     }
 93     if (p[2].size()) {
 94       bool can = 1;
 95       if (p[1].size() && p[1].front() > p[2].front()) can = 0;
 96       if (p[0].size() && p[0].front() > p[2].front()) can = 0;
 97       if (can) {
 98         ans += p[2].front();
 99         p[2].pop_front();
100         continue;
101       }
102     }
103   }
104   /*if (p[1].size()) {
105     while (cnt1 * 2 > num && cnt0 * 2 > num) {
106       if (!p[1].size() && !p[0].size()) break;
107       if (!p[1].size() || !p[0].size()) {
108         if (!p[1].size()) {
109           num++;
110           ans += p[0].front();
111           p[0].pop_front();
112         } else {
113           num++, cnt0++;
114           ans += p[1].front();
115           p[1].pop_front();
116         }
117       }
118       if (p[0].front() > p[1].front()) {
119         num++;
120         ans += p[0].front();
121         p[0].pop_front();
122       } else {
123         num++, cnt0++;
124         ans += p[1].front();
125         p[1].pop_front();
126       }
127     }
128   } else if (p[2].size()) {
129     while (cnt1 * 2 > num && cnt0 * 2 > num) {
130       if (!p[2].size() && !p[0].size()) break;
131       if (!p[2].size() || !p[0].size()) {
132         if (!p[2].size()) {
133           num++;
134           ans += p[0].front();
135           p[0].pop_front();
136         } else {
137           num++, cnt1++;
138           ans += p[2].front();
139           p[2].pop_front();
140         }
141       }
142       if (p[0].front() > p[2].front()) {
143         num++;
144         ans += p[0].front();
145         p[0].pop_front();
146       } else {
147         num++, cnt1++;
148         ans += p[2].front();
149         p[2].pop_front();
150       }
151     }
152   }
153   while (p[0].size() && cnt1 * 2 > num && cnt0 * 2 > num) {
154     num++;
155     ans += p[0].front();
156     p[0].pop_front();
157   }*/
158   Write(ans);
159   return 0;
160 }
Problem F

Problem G Monsters and Potions

題目大意

  (請耐心讀原題)

  暴力列舉拉力點,暴力列舉一下動的英雄。(能動就直接移動,不是爆搜)

  很好奇為什麼只有100多個隊過。

Code

  1 //Author: dream_maker
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 //----------------------------------------------
  5 //typename
  6 typedef long long ll;
  7 //convenient for
  8 #define fu(a, b, c) for (int a = b; a <= c; ++a)
  9 #define fd(a, b, c) for (int a = b; a >= c; --a)
 10 #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
 11 //inf of different typename
 12 const int INF_of_int = 1e9;
 13 const ll INF_of_ll = 1e18;
 14 //fast read and write
 15 template <typename T>
 16 void Read(T &x) {
 17   bool w = 1;x = 0;
 18   char c = getchar();
 19   while (!isdigit(c) && c != '-') c = getchar();
 20   if (c == '-') w = 0, c = getchar();
 21   while (isdigit(c)) {
 22     x = (x<<1) + (x<<3) + c -'0';
 23     c = getchar();
 24   }
 25   if (!w) x = -x;
 26 }
 27 template <typename T>
 28 void Write(T x) {
 29   if (x < 0) {
 30     putchar('-');
 31     x = -x; 
 32   }
 33   if (x > 9) Write(x / 10);
 34   putchar(x % 10 + '0');
 35 }
 36 //----------------------------------------------
 37 const int N = 1010;
 38 ll n, m;
 39 ll s[N], h[N], p[N];
 40 ll now[N], tp[N], tot;
 41 bool wk[N];
 42 void init() {
 43   fu(i, 1, n) now[i] = p[i];
 44   memset(tp, 0, sizeof(tp));
 45   memset(wk, 0, sizeof(wk));
 46   tot = 0;
 47 }
 48 bool check_walk(ll fro, ll to, ll vl) {
 49   if (fro == to) return 1;
 50   if (fro > to) {
 51     fd(i, fro, to) {
 52       if (now[i] < 0 && vl + now[i] < 0) return 0;
 53       vl += now[i];
 54     }
 55     return 1;
 56   } else {
 57     fu(i, fro, to) {
 58       if (now[i] < 0 && vl + now[i] < 0) return 0;
 59       vl += now[i];
 60     }
 61     return 1;
 62   }
 63 }
 64 void get_clean(ll l, ll r) {
 65   if (l >= r) {
 66     fd(i, l, r) now[i] = 0;
 67   } else {
 68     fu(i, l, r) now[i] = 0;
 69   }
 70 }
 71 struct Node {
 72   int id, dis;
 73 } w[N];
 74 bool cmp(Node a, Node b) {
 75   return a.dis < b.dis;
 76 }
 77 bool check(int pos) {
 78   init();
 79   fu(i, 1, m) {
 80     w[i].id = i;
 81     w[i].dis = labs(pos - s[i]);
 82   }
 83   sort(w + 1, w + m + 1, cmp);
 84   fu(i, 1, m) {
 85     if (check_walk(s[w[i].id], pos, h[w[i].id])) {
 86       tp[++tot] = w[i].id;
 87       get_clean(s[w[i].id], pos);
 88       wk[w[i].id] = 1;
 89     }
 90   }
 91   fu(i, 1, m) {
 92     if (!wk[w[i].id]) { 
 93       if (!check_walk(s[w[i].id], pos, h[w[i].id])) return 0;
 94       tp[++tot] = w[i].id;
 95       wk[w[i].id] = 1;
 96     }
 97   }
 98   Write(pos); putchar('\n');
 99   fu(i, 1, m) {
100     Write(tp[i]);
101     putchar(' ');
102   }
103   return 1;
104 }
105 int main() {
106   Read(n), Read(m);
107   fu(i, 1, m) Read(s[i]), Read(h[i]);
108   fu(i, 1, n) Read(p[i]);
109   fu(i, 1, n)
110     if (check(i)) return 0;
111   printf("-1");
112   return 0;
113 }
Problem G

Problem H BerOS File Suggestion

題目大意

  給定$n$個字串,每次詢問一個字串,問有多少個字串包含它作為子串,然後要求隨便輸出$n$個串中任意一個滿足條件的串。

  居然有人寫AC自動機。牛逼。

  我直接Hash。好像可以直接開一個string對映到xxx的map。

  感覺我對STL一無所知。

Code

 1 /**
 2  * Codeforces
 3