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$使得按照下面方式完成的任务尽量多。

  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  * Problem#1070E
 4  * Accepted
 5  * Time: 234ms
 6  * Memory: 15900k
 7  * Author: yyf
 8  */
 9 #include <iostream>
10 #include <cstdlib>
11 #include <cstdio>
12 #include <map>
13 using namespace std;
14 typedef bool boolean;
15 #define ull unsigned long long
16
17 ull base = 233;
18
19 const int N = 1e4 + 3;
20
21 int n, q;
22 char strs[N][10];
23 map<ull, int> cnt;
24 map<ull, int> lst;
25
26 inline void init() {
27     scanf("%d", &n);
28     for (int i = 1; i <= n; i++) {
29         scanf("%s", strs[i]);
30         char *s = strs[i];
31         for (int l = 0; s[l]; l++) {
32             ull ha = 0;
33             for (int r = l; s[r]; r++) {
34                 ha = ha * base + s[r];
35                 if (lst[ha] != i) {
36                     lst[ha] = i;
37                     cnt[ha]++;
38 //                    cerr << "added" << " " << ha << endl;
39                 }
40             }
41         }
42     }
43 }
44
45 char str[10];
46 inline void solve() {
47     scanf("%d", &q);
48     while (q--) {
49         scanf("%s", str);
50         ull ha = 0;
51         for (int i = 0; str[i]; i++)
52             ha = ha * base + str[i];
53         int r1 = cnt[ha];
54         if (r1)
55             printf("%d %s\n", r1, strs[lst[ha]]);
56         else
57             puts("0 -");
58     }
59 }
60
61 int main() {
62     init();
63     solve();
64     return 0;
65 }

Problem H

Problem I Privatization of Roads in Berland

题目大意

  给定一个$n$个点$m$条边的无向图,有足够多个公司,将每条边分配给一个公司,满足:

  1. 一个公司最多拥有两条边
  2. 每个顶点相邻的边至多被分给$K$个公司。

  容易发现,如果一个公司拥有了两条边,那么它存在一个公共顶点会比较优。

  考虑如果一个顶点的度数大于$K$,那么我们就要硬点它周边$2(d - k)$条边两两配对。

  然后每条边建一个点做匹配就完了。

Code

  1 /**
  2  * Codeforces
  3  * Problem#1070I
  4  * Accepted
  5  * Time: 31ms
  6  * Memory: 200k
  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 typedef class Edge {
 38     public:
 39         int ed, nx, cap, f;
 40
 41         Edge() {    }
 42         Edge(int ed, int nx, int cap, int f):ed(ed), nx(nx), cap(cap), f(f) {    }
 43 }Edge;
 44
 45 typedef class MapManager {
 46     public:
 47         int *h;
 48         vector<Edge> es;
 49
 50         MapManager() {    }
 51         MapManager(int n) {
 52              h = new int[(n + 1)];
 53              pfill(h, h + n + 1, -1);
 54         }
 55
 56         void addEdge(int u, int v, int cap, int f) {
 57             es.push_back(Edge(v, h[u], cap, f));
 58             h[u] = (signed) es.size() - 1;
 59         }
 60
 61         void addArc(int u, int v, int cap) {
 62             addEdge(u, v, cap, 0);
 63             addEdge(v, u, cap, cap);
 64         }
 65
 66         Edge& operator [] (int p) {
 67             return es[p];
 68         }
 69
 70         void clear() {
 71             delete[] h;
 72             es.clear();
 73         }
 74 }MapManager;
 75
 76 const int N = 605;
 77
 78 int n, m, K;
 79 int s = 0, t;
 80 int mxcap;
 81 int deg[N];
 82 MapManager g;
 83
 84 inline void init() {
 85     scanf("%d%d%d", &n, &m, &K);
 86     pfill(deg, deg + n + 1, 0);
 87     g = MapManager(n + m + 1);
 88     for (int i = 1, u, v; i <= m; i++) {
 89         scanf("%d%d", &u, &v);
 90         deg[u]++, deg[v]++;
 91         g.addArc(0, i, 1);
 92         g.addArc(i, u + m, 1);
 93         g.addArc(i, v + m, 1);
 94     }
 95     t = n + m + 1, mxcap = 0;
 96     for (int i = 1; i <= n; i++)
 97         if (deg[i] > K)
 98             g.addArc(i + m, t, (deg[i] - K) << 1), mxcap += deg[i] - K;
 99     mxcap <<= 1;
100 }
101
102 int cur[N << 1], _div[N << 1];
103
104 int dfs(int p, int mf) {
105     if (p == t || !mf)
106         return mf;
107     int f, flow = 0;
108     for (int& i = cur[p], e; ~i; i = g[i].nx) {
109         e = g[i].ed;
110         if (g[i].f < g[i].cap && _div[e] == _div[p] + 1 && (f = dfs(e, min(mf, g[i].cap - g[i].f))) > 0) {
111             g[i].f += f;
112             g[i ^ 1].f -= f;
113             mf -= f;
114             flow += f;
115             if (!mf)
116                 break;
117         }
118     }
119     return flow;
120 }
121
122 queue<int> que;
123 boolean bfs() {
124     pfill(_div, _div + t + 1, -1);
125     _div[s] = 0;
126     que.push(s);
127     while (!que.empty()) {
128         int e = que.front();
129         que.pop();
130         for (int i = g.h[e], eu; ~i; i = g[i].nx) {
131             eu = g[i].ed;
132             if (g[i].cap == g[i].f)
133                 continue;
134             if (~_div[eu])
135                 continue;
136             _div[eu] = _div[e] + 1;
137             que.push(eu);
138         }
139     }
140     return _div[t] != -1;
141 }
142
143 int dinic() {
144     int rt = 0;
145     while (bfs()) {
146         pcopy(cur, cur + t + 1, g.h);
147         rt += dfs(s, inf);
148     }
149     return rt;
150 }
151
152 int lab[N];
153 vector<int> mat[N];
154
155 inline void solve() {
156     int flow = dinic(), used = 0;
157
158     if (flow != mxcap) {
159         for (int i = 1; i <= m; i++)
160             printf("0 ");
161         putchar(‘\n‘);
162         return;
163     }
164
165     for (int i = 1; i <= n; i++)
166         mat[i].clear();
167
168     for (int i = 1; i <= m; i++)
169         for (int j = g.h[i]; ~j; j = g[j].nx)
170             if (g[j].cap == g[j].f && g[j].ed > m) {
171                 mat[g[j].ed - m].push_back(i);
172                 break;
173             }
174
175     pfill(lab + 1, lab + m + 1, 0);
176     for (int i = 1, a, b; i <= n; i++)
177         while (!mat[i].empty()) {
178             a = mat[i].back();
179             mat[i].pop_back();
180             b = mat[i].back();
181             mat[i].pop_back();
182
183             lab[a] = lab[b] = ++used;
184         }
185
186     for (int i = 1; i <= m; i++) {
187         if (!lab[i])
188             lab[i] = ++used;
189         printf("%d ", lab[i]);
190     }
191     putchar(‘\n‘);
192 }
193
194 inline void clear() {
195     g.clear();
196 }
197
198 int T;
199 int main() {
200     scanf("%d", &T);
201     while (T--) {
202         init();
203         solve();
204         clear();
205     }
206     return 0;
207 }

Problem I

Problem J Streets and Avenues in Berhattan

题目大意

  给定一个长度为$K$的字母串,以及$n, m$,要求在$K$中选出不同位置的$n$个字符和$m$个字符,使得$n$个字符中和$m$字符中相同的对数尽量小。

  容易发现算贡献的只有一种字符。

  然后枚举它,随便dp一下就过了。

  时间复杂度$O(n|\Sigma|^2)$

  感觉用多项式除法可以去掉一个平方。

Code

 1 /**
 2  * Codeforces
 3  * Problem#1070J
 4  * Accepted
 5  * Time: 46ms
 6  * Memory: 1200k
 7  * Author: yyf
 8  */
 9 #include <bits/stdc++.h>
10 using namespace std;
11 typedef bool boolean;
12
13 template <typename T>
14 void pfill(T* pst, const T* ped, T val) {
15     for ( ; pst != ped; *(pst++) = val);
16 }
17
18 const int N = 2e5 + 5, Alpha = 27;
19
20 int T;
21 int n, m, K;
22 int cnt[Alpha];
23 boolean f[N];
24 int g[N];
25 char str[N];
26
27 inline void init() {
28     scanf("%d%d%d", &n, &m, &K);
29     scanf("%s", str);
30     pfill(cnt, cnt + Alpha, 0);
31     for (char *p = str; *p; p++)
32         cnt[*p - ‘A‘]++;
33 }
34
35 inline void solve() {
36     int res = (signed) (~0u >> 1);
37     for (int i = 0, used, diff; i < Alpha && res; i++) {
38         pfill(f, f + K + 1, false);
39         f[0] = true;
40         for (int c = 0, s = 0; c < Alpha; c++)
41             if (cnt[c] && (c ^ i)) {
42                 for (int j = s; ~j; j--)
43                     f[j + cnt[c]] |= f[j];
44                 s += cnt[c];
45             }
46
47         for (int j = 0; j <= K; j++)
48             g[j] = (f[j] ? j : K + 1);
49         for (int j = K - 1; ~j; j--)
50             g[j] = min(g[j + 1], g[j]);
51
52         for (int c = 0; c <= cnt[i] && c <= n && res; c++) {
53             used = g[n - c] + c;
54             if (K - used >= m) {
55                 diff = K - cnt[i] - g[n - c];
56                 if (diff >= m)
57                     res = 0;
58                 else
59                     res = min(res, (m - diff) * c);
60             }
61         }
62     }
63     printf("%d\n", res);
64 }
65
66 int main() {
67     scanf("%d", &T);
68     while (T--) {
69         init();
70         solve();
71     }
72     return 0;
73 }

Problem J

Problem K Video Posts

题目大意

  (没听过)

  (听说是普及题)

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 = 1e5 + 10;
38 ll n, k, a[N], ans[N];
39 int main() {
40   Read(n), Read(k);
41   fu(i, 1, n) Read(a[i]), a[i] += a[i - 1];
42   if (a[n] % k) {
43     printf("No");
44     return 0;
45   }
46   ll len = a[n] / k, last = 0, tot = 0;
47   fu(i, 1, n) {
48     if (a[i] - a[last] == len) {
49       ans[++tot] = i - last;
50       last = i;
51     } else if(a[i] - a[last] > len) {
52       printf("No");
53       return 0;
54     }
55   }
56   printf("Yes\n");
57   fu(i, 1, k) {
58     Write(ans[i]);
59     putchar(‘ ‘);
60   }
61   return 0;
62 }

Problem K

Problem L Odd Federalization

题目大意

  要求把$n$个点$m$条边分成$r$个部分,使得每一部分每个点的度都是偶数(不看不在同一部分内的边),问最小的$r$和方案。

  首先来猜想答案小于等于2.

  然后把每个点在哪个集合看成未知数$x_i$。

  用异或算一下每个点被割掉的边的奇偶性,然后就可以列方程了。

  高斯消元 + bitset就没了。

Code

  1 /**
  2  * Codeforces
  3  * Problem#1070L
  4  * Accepted
  5  * Time: 93ms
  6  * Memory: 500k
  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 const int N = 2048;
 38
 39 int n, m;
 40 boolean deg[N];
 41 bitset<N> eq[N];
 42
 43 void reverse(bitset<N> &bs, int bit) {
 44     if (bs.test(bit))
 45         bs.reset(bit);
 46     else
 47         bs.set(bit);
 48 }
 49
 50 inline void init() {
 51     scanf("%d%d", &n, &m);
 52     pfill(deg, deg + n, false);
 53     for (int i = 0; i < n; i++)
 54         eq[i].reset();
 55     for (int i = 1, u, v; i <= m; i++) {
 56         scanf("%d%d", &u, &v);
 57         u--, v--;
 58         eq[u].set(v);
 59         eq[v].set(u);
 60         reverse(eq[u], u);
 61         reverse(eq[v], v);
 62         deg[u] = !deg[u], deg[v] = !deg[v];
 63     }
 64 }
 65
 66 void guass() {
 67     for (int i = 0; i < n; i++) {
 68         int p = -1;
 69         for (int j = i; j < n && p == -1; j++)
 70             if (eq[j].test(i))
 71                 p = j;
 72         if (p == -1)
 73             continue;
 74         swap(eq[p], eq[i]);
 75         swap(deg[p], deg[i]);
 76         for (int j = 0; j < n; j++)
 77             if ((j ^ i) && eq[j].test(i))
 78                 eq[j] ^= eq[i], deg[j] ^= deg[i];
 79     }
 80 }
 81
 82 inline void solve() {
 83     guass();
 84     int r = 1;
 85     for (int i = 0; i < n && r == 1; i++)
 86         if (deg[i])
 87             r = 2;
 88     printf("%d\n", r);
 89     for (int i = 0; i < n; i++)
 90         printf("%d ", deg[i] + 1);
 91     puts("");
 92 }
 93
 94 int T;
 95 int main() {
 96     scanf("%d", &T);
 97     while (T--) {
 98         init();
 99         solve();
100     }
101     return 0;
102 }

Problem L

原文地址:https://www.cnblogs.com/yyf0309/p/9823380.html

时间: 2024-10-11 03:59:00

2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror) Partial Solution的相关文章

2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror) 体验记

原文链接https://www.cnblogs.com/zhouzhendong/p/CF1070.html 比赛网址:http://codeforces.com/contest/1070 感受 本来只打算玩玩的. 结果玩的海星. 我做 A 题的时候可能比较浮躁吧,各种傻错误,爆了 7 个罚时. 我 A 还没过,cly 神仙已经把 CDK 切光了. 4点半过一会儿,各自回家.cly 要剃头,就咕咕咕了.我本来也要剃的,后来临时决定先打题. 然后过了 A ,顺手切掉了 H 和 F ,开了 E ,猜

2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)

http://codeforces.com/contest/1070 A 给你一个d和s,求一个最小的数,使的能整除d,并且每位数的和为s. 如果确定了某n位数取模d的值,那么再计算同样的n位数,取模d也是相同的值时,就多此一举了.比如10%2 == 0  20%2 == 0  同样是两位数,取模2都是等于0.所以取最小的就可以了. 1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const

2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) Solution

A. Find a Number Solved By 2017212212083 题意:$找一个最小的n使得n % d == 0 并且 n 的每一位数字加起来之和为s$ 思路: 定义一个二元组$<d, s>$ 表示当前状态模d的值,以及每一位加起来的值 跑最短路,从$<0, 0>  跑到 <0, s>$ 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 1e5 +

2018-2019 ICPC, NEERC, Southern Subregional Contest

目录 2018-2019 ICPC, NEERC, Southern Subregional Contest (Codeforces 1070) A.Find a Number(BFS) C.Cloud Computing(线段树) D.Garbage Disposal(模拟) E.Getting Deals Done(二分) F.Debate(贪心) H.BerOS File Suggestion(后缀自动机) I.Privatization of Roads in Berland(网络流)

模拟赛小结:2014-2015 ACM-ICPC, NEERC, Southern Subregional Contest

2014-2015 ACM-ICPC, NEERC, Southern Subregional Contest 2019年10月11日 15:30-20:30(Solved 6,Penalty 740) 国庆咸鱼十来天,回来又过了快一个星期,终于和队友约上了模拟赛.(周三拖周四,因为队(fei)友(zhai)们要跑1000米,又拖到周五QAQ) I:00:04.开场翻翻题目,机智如我很快找到一个贪心. D:00:36.看了看现场榜,有人交D.F和M,lh同学已经开F去了,xk同学说他M思路差不多

D. Dog Show 2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest, qualification stage (Online Mirror, ACM-ICPC Rules, Teams Preferred)

http://codeforces.com/contest/847/problem/D 巧妙的贪心 仔细琢磨... 像凸包里的处理 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <time.h> 6 #include <string> 7 #include <set> 8 #includ

NEERC Southern Subregional 2012

NEERC Southern Subregional 2012 Problem B. Chess Championship 题目描述:有两个序列\(a, b\),两个序列都有\(n\)个数,并且这\(2n\)个数两两不同,现在要将这两个序列里的数两两配对,组成\(n\)个数对,要求数对中\(a\)的数比\(b\)的数大的数对个数要比其它的多\(m\)个.问方案数. solution 将这\(2n\)个数从小到大排,预处理出前\(i\)个数中\(a, b\)的个数\(suma, sumb\), \

2013-2014 ACM-ICPC, NEERC, Eastern Subregional Contest PART (7/10)

\[2013-2014\ ACM-ICPC,\ NEERC,\ Eastern\ Subregional\ Contest\] \(A.Podracing\) \(B.The\ battle\ near\ the\ swamp\) 签到 //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<bits/stdc++.h> using namespace std; function<void(

ACM ICPC 2011–2012, NEERC, Northern Subregional Contest J. John’s Inversions(合并排序求逆序数对数)

题目链接:http://codeforces.com/gym/100609/attachments 题目大意:有n张牌,每张牌有红色和蓝色两面,两面分别写了一些数字,同种颜色的任意两个数字若排在前面的数字比排在后面的数字大就叫做一对逆序数.求怎样排序得到的逆序数对最少. 解题思路:其中一种颜色的数字是顺序且这种颜色数字相同时对应的另一种颜色的数字是顺序时得到的逆序数对数最少.难点在于求逆序数对数.因为数量很大O(n^2)复杂度不能满足,这里根据合并排序的原理求解每个数字前面有多少个比它大的数字,