爆炸自闭,题目太难。
题解会一直更新,这场题目太不好补了。
题目链接:https://ac.nowcoder.com/acm/contest/882#question
A:
题解就说是对小数据找规律……证明完全不会。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 #define mid (curl+curr>>1) 17 /* namespace */ 18 using namespace std; 19 /* header end */ 20 21 const ll mod = 1e9 + 7; 22 23 ll qp(ll x, ll b) { 24 ll ret = 1; 25 while (b) { 26 if (b & 1) ret = ret * x % mod; 27 x = x * x % mod; 28 b >>= 1; 29 } 30 return ret; 31 } 32 33 ll n, m, ans = 1; 34 35 int main() { 36 int t; scanf("%d", &t); 37 while (t--) { 38 scanf("%lld%lld", &n, &m); 39 if (n == 1) printf("%lld ", ans); 40 else { 41 if (!m) ans = 0; 42 else ans = ans * qp(n - 1, mod - 2) % mod; 43 printf("%lld ", ans); 44 } 45 } 46 return 0; 47 }
B:
dp?
C:
贼恐怖的数据结构题,线段树+link-cut tree。
D:
让人自闭的图论题,结果题解就说是暴力。
E:
线段树维护dp,跟昨天的套路一样。
F:
听题解说得特别简单,是组合数暴力,但是有优化技巧。
然而我选择爆搜+剪枝。隔壁队还有模拟退火过的,也是nb。
但是爆搜不是正向爆搜,是反向的。ans=所有competitive value减去队内competitive value
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 #define mid (curl+curr>>1) 17 /* namespace */ 18 using namespace std; 19 /* header end */ 20 21 const int maxn = 30; 22 int n, a[maxn], b[maxn], v[maxn][maxn], vis[maxn]; 23 ll ans = ll_inf, totCmp = 0; 24 25 void dfs(int depth, int curr, ll sum) { 26 if (sum >= ans) return; 27 if (depth >= n) { 28 int b0 = b[0]; 29 if (b[0] != n) 30 for (int i = a[a[0]] + 1; i < 2 * n; i++) { 31 for (int j = 1; j <= b[0]; j++) sum += v[i][b[j]]; 32 b[++b[0]] = i; 33 } 34 ans = min(ans, sum); 35 b[0] = b0; 36 return; 37 } 38 ll addB = 0; 39 int a0 = a[0], b0 = b[0]; 40 rep1(i, curr, n + depth) { 41 ll addA = 0; 42 rep1(j, 1, a[0]) addA += v[i][a[j]]; 43 a[++a[0]] = i; 44 dfs(depth + 1, i + 1, sum + addA + addB); 45 a[0]--; 46 rep1(j, 1, b[0]) addB += v[i][b[j]]; 47 b[++b[0]] = i; 48 } 49 a[0] = a0, b[0] = b0; 50 } 51 52 int main() { 53 memset(vis, 0, sizeof(vis)); 54 scanf("%d", &n); 55 rep0(i, 0, 2 * n) { 56 rep0(j, 0, 2 * n) 57 scanf("%d", &v[i][j]); 58 } 59 rep0(i, 0, 2 * n) { 60 rep0(j, i + 1, 2 * n) totCmp += v[i][j]; 61 } 62 dfs(0, 0, 0); 63 printf("%lld ", totCmp - ans); 64 return 0; 65 }
G:
没人做的几何题。
H:
队友做的题。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<vector> 5 #include<queue> 6 #include<set> 7 using namespace std; 8 const int maxn = 1500; 9 10 int M[maxn][maxn]; 11 int Link[maxn], Left[maxn], Right[maxn]; 12 string s; 13 vector<int> ans; 14 15 bool CMP(int a, int b) { 16 return a > b; 17 } 18 19 int main() { 20 int n, m; 21 int fmax = 0, smax = 0; 22 cin >> n >> m; 23 for (int i = 1; i <= n; i++) { 24 cin >> s; 25 for (int j = 1; j <= m; j++) { 26 M[i][j] = s[j - 1] - '0'; 27 } 28 } 29 for (int i = 1; i <= m; i++) { 30 Link[i] = 0; 31 Left[i] = 1; 32 Right[i] = m ; 33 } 34 int hight, width; 35 for (int i = 1; i <= n; i++) { 36 int nowl = 0; 37 for (int j = 1; j <= m; j++) { 38 if (M[i][j] == 0) { 39 Link[j] = 0; 40 nowl = j; 41 Left[j] = 1; 42 } else { 43 Left[j] = max(Left[j], nowl + 1); 44 Link[j] ++; 45 } 46 } 47 int nowr = m + 1 ; 48 set<int> S; 49 S.clear(); 50 for (int j = m; j >= 1; j--) { 51 if (M[i][j] == 0) { 52 nowr = j ; 53 Right[j] = m; 54 S.clear(); 55 } else { 56 Right[j] = min(nowr - 1, Right[j]); 57 int s = (Link[j] * (Right[j] - Left[j] + 1)); 58 if (S.count(s)) { 59 continue; 60 } 61 S.insert(s); 62 if (s >= fmax) { 63 smax = fmax; 64 fmax = s; 65 hight = Link[j]; 66 width = (Right[j] - Left[j] + 1); 67 } else if (s > smax) { 68 smax = s; 69 } 70 } 71 } 72 } 73 cout << max(smax, max(hight * (width - 1), (hight - 1) * width)) << endl; 74 return 0; 75 }
赛后upsolved代码。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 #define mid (curl+curr>>1) 17 /* namespace */ 18 using namespace std; 19 /* header end */ 20 21 const int maxn = 1e3 + 10; 22 char s[maxn][maxn]; 23 int h[maxn], n, m, maxx = 0, maxx2 = 0, x, y; 24 25 int main() { 26 scanf("%d%d", &n, &m); 27 rep0(i, 0, n) scanf("%s", s[i]); 28 rep0(i, 0, n) { 29 rep0(j, 0, m) { 30 if (s[i][j] == '1') h[j]++; 31 else h[j] = 0; 32 } 33 stack<int>q; 34 rep0(j, 0, m) { 35 while (!q.empty() && h[j] <= h[q.top()]) { 36 int l = q.top(); 37 q.pop(); 38 int k = q.empty() ? -1 : q.top(), sum = (j - k - 1) * h[l]; 39 if (sum > maxx) { 40 x = j - k - 1; 41 y = h[l]; 42 maxx2 = maxx; maxx = sum; 43 } else if (sum > maxx2) maxx2 = sum; 44 } 45 q.push(j); 46 } 47 if (!q.empty()) { 48 int l = q.top(); 49 q.pop(); 50 int k = q.empty() ? -1 : q.top(); 51 int sum = (m - k - 1) * h[l]; 52 if (sum > maxx) { 53 x = m - k - 1; 54 y = h[l]; 55 maxx2 = maxx; maxx = sum; 56 } else if (sum > maxx2) maxx2 = sum; 57 } 58 } 59 int ans = max(max(maxx - x, maxx - y), maxx2); 60 printf("%d ", ans); 61 return 0; 62 }
I:
又是dp?题目看懂了,然而一脸懵逼完全不知道怎么做。
J:
开场不知道是哪两个闸总1A,害得我以为是水题(wdnmd)。看了好久才发现开错题。
当时感觉是个数据结构xjb维护,题解居然是暴力……
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 #define mid (curl+curr>>1) 17 /* namespace */ 18 using namespace std; 19 /* header end */ 20 21 // const int maxn = 1e6 + 10, maxm = 2e7 + 10; 22 const int maxn = 10, maxm = 20; 23 ll sum = 0; 24 int s[maxm], l[maxn], r[maxn], p[maxn]; 25 int n, x = 0, now = 0, zero = 10, k = 0, st = zero, L = zero, R = zero; 26 27 // 只包含1的区间称为1区间,只包含0的区间称为0区间 28 int main() { 29 scanf("%d", &n); 30 rep1(i, 1, n) scanf("%d%d", &l[i], &r[i]); 31 // p是前缀和,维护当前1区间和前面的0区间抵消之后剩下1的个数 32 rep1(i, 1, n) p[i] = p[i - 1] + (r[i] - l[i] + 1) - (l[i] - r[i - 1] - 1); 33 for (int i = n - 1; i >= 1; i--) p[i] = max(p[i], p[i + 1]); 34 s[zero] = 1; 35 rep1(i, 1, n) { 36 while (x < l[i]) { 37 if (!now && k - p[i] < l[i] && k > p[i]) { 38 x += k - p[i]; 39 k = p[i]; 40 st = L = zero; 41 R = zero - 1; 42 } 43 x++, k--, st--; 44 if (st < L) { 45 L--; s[st] = 0; 46 } 47 now -= s[st]++; 48 sum += now; 49 } 50 while (x <= r[i]) { 51 x++, k++; 52 now += s[st++]; 53 sum += now; 54 if (st > R) { 55 R++; 56 s[st] = 0; 57 } 58 s[st]++; 59 } 60 } 61 while (now > 0 && x < 1e9 && st >= 0 && st <= 2 * zero) { 62 x++; 63 now -= s[--st]++; 64 sum += now; 65 } 66 printf("%lld ", sum); 67 return 0; 68 }