AtCoder Grand Contest 015 题解
A - A+...+B Problem
可以取到的值一定是一段区间。所以答案即为max-min+1
1 //waz 2 #include <bits/stdc++.h> 3 4 using namespace std; 5 6 #define mp make_pair 7 #define pb push_back 8 #define fi first 9 #define se second 10 #define ALL(x) (x).begin(), (x).end() 11 #define SZ(x) ((int)((x).size())) 12 13 typedef pair<int, int> PII; 14 typedef vector<int> VI; 15 typedef long long int64; 16 typedef unsigned int uint; 17 typedef unsigned long long uint64; 18 19 #define gi(x) ((x) = F()) 20 #define gii(x, y) (gi(x), gi(y)) 21 #define giii(x, y, z) (gii(x, y), gi(z)) 22 23 int F() 24 { 25 char ch; 26 int x, a; 27 while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-'); 28 if (ch == '-') ch = getchar(), a = -1; 29 else a = 1; 30 x = ch - '0'; 31 while (ch = getchar(), ch >= '0' && ch <= '9') 32 x = (x << 1) + (x << 3) + ch - '0'; 33 return a * x; 34 } 35 36 int N, A, B; 37 38 int main() 39 { 40 giii(N, A, B); 41 B -= A; 42 int64 v = 1LL * (N - 1) * B - B + 1; 43 printf("%lld\n", v > 0 ? v : 0LL); 44 }
B - Evilator
首先如果方向不对就是2步,要不然就是一步,直接统计即可。
1 //waz 2 #include <bits/stdc++.h> 3 4 using namespace std; 5 6 #define mp make_pair 7 #define pb push_back 8 #define fi first 9 #define se second 10 #define ALL(x) (x).begin(), (x).end() 11 #define SZ(x) ((int)((x).size())) 12 13 typedef pair<int, int> PII; 14 typedef vector<int> VI; 15 typedef long long int64; 16 typedef unsigned int uint; 17 typedef unsigned long long uint64; 18 19 #define gi(x) ((x) = F()) 20 #define gii(x, y) (gi(x), gi(y)) 21 #define giii(x, y, z) (gii(x, y), gi(z)) 22 23 int F() 24 { 25 char ch; 26 int x, a; 27 while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-'); 28 if (ch == '-') ch = getchar(), a = -1; 29 else a = 1; 30 x = ch - '0'; 31 while (ch = getchar(), ch >= '0' && ch <= '9') 32 x = (x << 1) + (x << 3) + ch - '0'; 33 return a * x; 34 } 35 36 const int N = 1e5 + 10; 37 38 char str[N]; 39 40 int n; 41 42 long long ans; 43 44 int main() 45 { 46 scanf("%s", str + 1); 47 n = strlen(str + 1); 48 for (int i = 1; i <= n; ++i) 49 { 50 if (str[i] == 'U') 51 { 52 ans += 2 * (i - 1); 53 } 54 else 55 ans += i - 1; 56 } 57 //cerr << ans << endl; 58 reverse(str + 1, str + n + 1); 59 //cnt = 0; 60 for (int i = 1; i <= n; ++i) 61 { 62 if (str[i] == 'D') 63 { 64 ans += 2 * (i - 1); 65 } 66 else 67 ans += i - 1; 68 } 69 printf("%lld\n", ans); 70 }
C - Nuske vs Phantom Thnook
图是一棵树,树的连通块个数=点数-边数,那么直接前缀和求点数、边数即可。
1 //waz 2 #include <bits/stdc++.h> 3 4 using namespace std; 5 6 #define mp make_pair 7 #define pb push_back 8 #define fi first 9 #define se second 10 #define ALL(x) (x).begin(), (x).end() 11 #define SZ(x) ((int)((x).size())) 12 13 typedef pair<int, int> PII; 14 typedef vector<int> VI; 15 typedef long long int64; 16 typedef unsigned int uint; 17 typedef unsigned long long uint64; 18 19 #define gi(x) ((x) = F()) 20 #define gii(x, y) (gi(x), gi(y)) 21 #define giii(x, y, z) (gii(x, y), gi(z)) 22 23 int F() 24 { 25 char ch; 26 int x, a; 27 while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-'); 28 if (ch == '-') ch = getchar(), a = -1; 29 else a = 1; 30 x = ch - '0'; 31 while (ch = getchar(), ch >= '0' && ch <= '9') 32 x = (x << 1) + (x << 3) + ch - '0'; 33 return a * x; 34 } 35 36 char str[2010][2010]; 37 38 int a[2010][2010], b[2010][2010], c[2010][2010]; 39 40 int n, m, q; 41 42 int main() 43 { 44 giii(n, m, q); 45 for (int i = 1; i <= n; ++i) scanf("%s", str[i] + 1); 46 for (int i = 1; i <= n; ++i) 47 { 48 for (int j = 1; j <= m; ++j) 49 if (str[i][j] == '1') ++a[i][j]; 50 for (int j = 1; j < m; ++j) 51 if (str[i][j] == '1' && str[i][j + 1] == '1') ++b[i][j]; 52 if (i < n) 53 for (int j = 1; j <= m; ++j) 54 if (str[i][j] == '1' && str[i + 1][j] == '1') ++c[i][j]; 55 } 56 for (int i = 1; i <= n; ++i) 57 for (int j = 1; j <= m; ++j) 58 { 59 a[i][j] += a[i][j - 1] + a[i - 1][j] - a[i - 1][j - 1]; 60 b[i][j] += b[i][j - 1] + b[i - 1][j] - b[i - 1][j - 1]; 61 c[i][j] += c[i][j - 1] + c[i - 1][j] - c[i - 1][j - 1]; 62 } 63 while (q--) 64 { 65 int x1, y1, x2, y2; 66 gii(x1, y1); 67 gii(x2, y2); 68 int A = a[x2][y2] + a[x1 - 1][y1 - 1] - a[x2][y1 - 1] - a[x1 - 1][y2]; 69 //cerr << "A = " << a[x2][y2] << endl; 70 int B = b[x2][y2 - 1] + b[x1 - 1][y1 - 1] - b[x2][y1 - 1] - b[x1 - 1][y2 - 1]; 71 int C = c[x2 - 1][y2] + c[x1 - 1][y1 - 1] - c[x2 - 1][y1 - 1] - c[x1 - 1][y2]; 72 printf("%d\n", A - B - C); 73 } 74 return 0; 75 }
D - A or...or B Problem
我们考虑第一次出现不同位置的地方,令A和B最高位不同,然后分类讨论即可。
1 //waz 2 #include <bits/stdc++.h> 3 4 using namespace std; 5 6 #define mp make_pair 7 #define pb push_back 8 #define fi first 9 #define se second 10 #define ALL(x) (x).begin(), (x).end() 11 #define SZ(x) ((int)((x).size())) 12 13 typedef pair<int, int> PII; 14 typedef vector<int> VI; 15 typedef long long int64; 16 typedef unsigned int uint; 17 typedef unsigned long long uint64; 18 19 #define gi(x) ((x) = F()) 20 #define gii(x, y) (gi(x), gi(y)) 21 #define giii(x, y, z) (gii(x, y), gi(z)) 22 23 int F() 24 { 25 char ch; 26 int x, a; 27 while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-'); 28 if (ch == '-') ch = getchar(), a = -1; 29 else a = 1; 30 x = ch - '0'; 31 while (ch = getchar(), ch >= '0' && ch <= '9') 32 x = (x << 1) + (x << 3) + ch - '0'; 33 return a * x; 34 } 35 36 int64 A, B; 37 38 int main() 39 { 40 scanf("%lld%lld", &A, &B); 41 int p = 60; 42 if (A == B) 43 { 44 puts("1"); 45 return 0; 46 } 47 while (!((A ^ B) & (1LL << p))) --p; 48 int q = p - 1; 49 while ((~q) && !(B & (1LL << q))) --q; 50 int64 x = (1LL << p) - (A & ((1LL << p) - 1)); 51 int64 yl = (1LL << p), yr = (1LL << p) + (1LL << (q + 1)); 52 int64 zl = (1LL << p) + (A & ((1LL << p) - 1)), zr = 2 * (1LL << p); 53 int64 ans = x + yr - yl + zr - zl; 54 if (zl <= yr) 55 ans -= yr - zl; 56 printf("%lld\n", ans); 57 return 0; 58 }
E - Mr.Aoki Incubator
我们发现本质就是区间覆盖问题,线段树dp即可。
1 //waz 2 #include <bits/stdc++.h> 3 4 using namespace std; 5 6 #define mp make_pair 7 #define pb push_back 8 #define fi first 9 #define se second 10 #define ALL(x) (x).begin(), (x).end() 11 #define SZ(x) ((int)((x).size())) 12 13 typedef pair<int, int> PII; 14 typedef vector<int> VI; 15 typedef long long int64; 16 typedef unsigned int uint; 17 typedef unsigned long long uint64; 18 19 #define gi(x) ((x) = F()) 20 #define gii(x, y) (gi(x), gi(y)) 21 #define giii(x, y, z) (gii(x, y), gi(z)) 22 23 int F() 24 { 25 char ch; 26 int x, a; 27 while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-'); 28 if (ch == '-') ch = getchar(), a = -1; 29 else a = 1; 30 x = ch - '0'; 31 while (ch = getchar(), ch >= '0' && ch <= '9') 32 x = (x << 1) + (x << 3) + ch - '0'; 33 return a * x; 34 } 35 36 const int mod = 1e9 + 7; 37 38 const int N = 2e5 + 10; 39 40 int n; 41 42 PII t[N]; 43 44 int id[N]; 45 46 int L[N], R[N]; 47 48 VI q[N]; 49 50 bool comp(const int &i, const int &j) 51 { 52 return t[i].se < t[j].se; 53 } 54 55 int tr[N]; 56 57 void add(int x, int v) 58 { 59 ++x; 60 for (; x < N; x += x & -x) (tr[x] += v) %= mod; 61 } 62 63 int sum(int x) 64 { 65 ++x; 66 int v = 0; 67 for (; x; x -= x & -x) (v += tr[x]) %= mod; 68 return v; 69 } 70 71 int query(int l, int r) 72 { 73 return (sum(r) - sum(l - 1) + mod) % mod; 74 } 75 76 int main() 77 { 78 gi(n); 79 for (int i = 1; i <= n; ++i) 80 gii(t[i].se, t[i].fi), id[i] = i; 81 sort(t + 1, t + n + 1); 82 sort(id + 1, id + n + 1, comp); 83 int mi = n, mx = 0; 84 for (int i = n; i; --i) 85 { 86 mi = min(mi, id[i]); 87 L[i] = mi; 88 } 89 for (int i = 1; i <= n; ++i) 90 { 91 mx = max(mx, id[i]); 92 R[i] = mx; 93 q[R[i]].pb(L[i]); 94 //cerr << L[i] << ", " << R[i] << endl; 95 } 96 add(0, 1); 97 for (int r = 1; r <= n; ++r) 98 for (auto l : q[r]) 99 add(r, query(l - 1, r)); 100 printf("%d\n", query(n, n)); 101 return 0; 102 }
F - Kenus the Ancient Greek
只会最优解,目前还不会方案数