2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror) Partial Solution
從這裡開始
- 題目列表
- 瞎扯
- Problem A Find a Number
- Problem B Berkomnadzor
- Problem C Cloud Computing
- Problem D Garbage Disposal
- Problem E Getting Deals Done
- Problem F Debate
- Problem G Monsters and Potions
- Problem H BerOS File Suggestion
- Problem I Privatization of Roads in Berland
- Problem J Streets and Avenues in Berhattan
- Problem K Video Posts
- Problem L Odd Federalization
- Problem M Algoland and Berland
瞎扯
又來打比賽了,發現自己菜得不行。
果然我是標準的普及組選手。(這個隊名是啥意思?我也不知道,因為不知道取啥隊名,就隨機在鍵盤上敲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$使得按照下面方式完成的任務儘量多。
- 按順序完成$p_i \leqslant d$的任務
- 每做$m$個任務需要休息與做這$m$個任務花費的時間相等的時間。
yangkai覺得這玩意兒可以三分,於是我們成功得到了-5.
發現有用的$d$一定時某個$p_i$,可以把$p_i$排序,按順序插進樹狀陣列。
每次可以二分一下求出能夠完成的任務的數量。
時間複雜度$O(n\log^{2} n)$。
但是這個可以二分答案。
判斷條件是是否能夠把所有可做的任務做完。
答案只可能是它或者它加上1後的情況,
因為再大的時候不會花更少的時間去做數量相同的任務。
然後我的垃圾做法就被暴打了。
然後注意幾個地方:
- $p$相同的任務要一起加入樹狀陣列
- 樹狀陣列求第$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