标签:
A:这题利用单调栈,先预处理出每个位置向下的最远位置,那么每一行单独考虑,每行就相当于一些段的子矩阵个数,利用单调栈维护,每次出栈的时候把大于当前要入栈(高度0的不入栈了)的段的部分计算出来,累加一下答案即可
B:这题可以枚举,因为一个10^15开3方之后是10^5枚举起来是没有问题的,然后枚举一个数字i,等于要计算在max(a, i * i * i)到min(i * i * i, b)区间,有多少个x满足i * i * x在区间内,两边除下减下就能计算出答案了
C:并查集,注意每次合并的时候都要让城市作为根,最后对于人和服务找根,如果根的范围是城市,就表明信息是是全的
D:水题,用字符串存浮点数去计算,gcd约分下即可
E:这题。。显然没有很奇葩的数据,于是只要把不能互相在一个集合的连边,然后利用二分图染色判定,如果矛盾就无解,如果不矛盾,每次就取一个子集内黑白点多的一边累加,得到的答案就是最终答案
F:树形DP,dp[u][0]和dp[u][1]分别表示不回,回树根的最小代价,那么对于一个子树,回树根的代价是固定的,就是他的子树代价+边权,那么不回的代价就是任意选一个子树不回,这样的话,只要在找子节点的过程中,记录这个答案的最大值,那么用dp[u][1]减去这个值就能得到dp[u][0]的最小值
G:大白书上有这题,先对火做一个BFS计算出每个点的蔓延时间,然后利用这个时间,在对人做一个BFS,注意这题有个坑点,就是如果人走到出口就直接出去了,因为岩浆是后蔓延到的
H:贪心,对于y操作,最好的肯定是把后面的1放到前面的0的位置,那么就是要找一个临界值,后面放X个1,其余都使用x操作一步步挪到前面,这个直接枚举,然后维护一些前缀和七七八八的东西。写起来还是要注意细节,具体见代码
代码:
A:
#include <cstdio> #include <cstring> #include <stack> using namespace std; typedef long long ll; const int N = 2005; int n, m; char str[N]; int g[N][N]; stack<pair<int, int> > S; ll get(int s, int k) { return (ll)(2 * s - (k - 1)) * k / 2; } int main() { while (~scanf("%d%d", &n, &m)) { for (int i = 0; i < n; i++) { scanf("%s", str); for (int j = 0; j < m; j++) { if (str[j] == 'b') g[i][j] = 0; else g[i][j] = 1; } } for (int i = 0; i < m; i++) { int pre = n; for (int j = n - 1; j >= 0; j--) { if (g[j][i] == 0) pre = j; g[j][i] = pre; } } for (int i = 0; i < n; i++) g[i][m] = i; ll ans = 0; for (int i = 0; i < n; i++) { for (int j = 0; j <= m; j++) { int h = g[i][j] - i, v = j, pre = j; while (!S.empty() && S.top().first > h) { v = S.top().second; ans += get(j - v, pre - v) * (S.top().first - h); pre = v; S.pop(); } if (h) S.push(make_pair(h, v)); } } printf("%I64d\n", ans); } return 0; }
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; ll a, b; ll ans; int main() { while (~scanf("%I64d%I64d", &a, &b)) { ans = 0; for (ll i = 1; i * i * i <= b; i++) { ll sb = max(a, i * i * i); ans += b / (i * i) - (sb - 1) / (i * i); } printf("%I64d\n", ans); } return 0; }
#include <cstdio> #include <cstring> #include <vector> using namespace std; const int MAXN = 400005; const int N = 100000; const int M = 100000; int n, m, q; int parent[MAXN]; int find(int x) { if (x == parent[x])return x; return parent[x] = find(parent[x]); } void uni(int a, int b) { int pa = find(a); int pb = find(b); if (pb < pa) swap(pb, pa); if (pa != pb) parent[pa] = pb; } int main() { while (~scanf("%d%d%d", &n, &m, &q)) { int a, b, c; for (int i = 0; i < MAXN; i++) parent[i] = i; for (int i = 1; i <= n; i++) { scanf("%d%d", &a, &b); a--; b--; if (b != -1) { uni(a, b + N + M); } } for (int i = 1; i <= m; i++) { scanf("%d%d%d", &a, &b, &c); a--; b--; c--; uni(a + N, b); if (c != -1) { uni(a + N, c + N + M); uni(b, c + N + M); } } int tp,id; while (q--) { scanf("%d%d", &tp, &id); id--; if (tp == 1) id += N; int x = find(id); if (x >= N + M) printf("%d\n", x - (N + M) + 1); else printf("0\n"); } } return 0; }
#include <cstdio> #include <cstring> int t; char n[105]; typedef long long ll; ll gcd(ll a, ll b) { if (!b) return a; return gcd(b, a % b); } int main() { scanf("%d", &t); while (t--) { scanf("%s", &n); int len = strlen(n); ll sb = 0, fuck = 1; for (int i = 0; i < len; i++) { if (n[i] == '.') { for (int j = i + 1; j < len; j++) { sb = sb * 10 + n[j] - '0'; fuck *= 10; } break; } sb = sb * 10 + n[i] - '0'; } ll d = gcd(sb, fuck); printf("%I64d/%I64d\n", sb / d, fuck / d); } return 0; }
#include <cstdio> #include <cstring> #include <set> #include <vector> #include <algorithm> using namespace std; typedef long long ll; const int N = 50005; int n, col[N]; vector<int> g[N]; struct Point { int x, y; void read() { scanf("%d%d", &x, &y); } } p[N]; bool cmpx(Point a, Point b) { return a.x < b.x; } int w[2], ans; bool dfs(int u) { for (int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if (col[u] == col[v]) return false; if (col[v] == -1) { col[v] = !col[u]; w[col[v]]++; dfs(v); } } return true; } ll dis(Point a, Point b) { ll dx = a.x - b.x; ll dy = a.y - b.y; return dx * dx + dy * dy; } int main() { while (~scanf("%d", &n)) { for (int i = 0; i < n; i++) { p[i].read(); g[i].clear(); col[i] = -1; } sort(p, p + n, cmpx); for (int i = 0; i < n; i++) { for (int j = i + 1; p[j].x - p[i].x <= 5; j++) { if (dis(p[j], p[i]) <= 25LL) { g[i].push_back(j); g[j].push_back(i); } } } int flag = 0; ans = 0; for (int i = 0; i < n; i++) { if (col[i] == -1) { col[i] = 0; w[0] = 1; w[1] = 0; if (!dfs(i)) { flag = 1; break; } ans += max(w[0], w[1]); } } if (flag) printf("-1\n"); else printf("%d\n", ans); } return 0; }
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <vector> using namespace std; const int N = 100005; int n; const int INF = 0x3f3f3f3f; int cost[N], vis[N], dp[N][2]; vector<int> g[N]; void dfs(int u) { dp[u][0] = dp[u][1] = 0; if (g[u].size() == 0) return; int Min = -INF, Minv; for (int i = 0; i < g[u].size(); i++) { int v = g[u][i]; dfs(v); if (Min < dp[v][1] - dp[v][0] + cost[v]) { Min = dp[v][1] - dp[v][0] + cost[v]; Minv = v; } dp[u][1] += dp[v][1] + cost[v]; } dp[u][0] = dp[u][1] - dp[Minv][1] - cost[Minv] + dp[Minv][0]; } int main() { while (~scanf("%d", &n)) { int u, v, w; for (int i = 1; i <= n; i++) { vis[i] = 0; g[i].clear(); } for (int i = 0; i < n - 1; i++) { scanf("%d%d%d", &u, &v, &w); g[u].push_back(v); cost[v] = w; } dfs(1); printf("%d\n", dp[1][0]); } return 0; }
#include <cstdio> #include <cstring> #include <queue> using namespace std; const int N = 1005; const int INF = 0x3f3f3f3f; char g[N][N]; int t, n, m; struct Point { int x, y; Point() {} Point(int x, int y){ this->x = x; this->y = y; } } s, e; const int d[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; int bid[N][N], vis[N][N]; int main() { scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); queue<Point> Q; for (int i = 0; i < n; i++) { scanf("%s", g[i]); for (int j = 0; j < m; j++) { bid[i][j] = INF; vis[i][j] = INF; if (g[i][j] == 'S') { s.x = i; s.y = j; } if (g[i][j] == '!') { Q.push(Point(i, j)); bid[i][j] = 0; } if (g[i][j] == 'E') { e.x = i; e.y = j; } } } while (!Q.empty()) { Point u = Q.front(); Q.pop(); for (int i = 0; i < 4; i++) { Point v; v.x = u.x + d[i][0]; v.y = u.y + d[i][1]; if (v.x < 0 || v.x >= n || v.y < 0 || v.y >= m || g[v.x][v.y] == '#') continue; if (bid[v.x][v.y] > bid[u.x][u.y] + 1) { bid[v.x][v.y] = bid[u.x][u.y] + 1; Q.push(v); } } } Q.push(s); vis[s.x][s.y] = 0; int flag = 0; while (!Q.empty()) { Point u = Q.front(); Q.pop(); for (int i = 0; i < 4; i++) { Point v; v.x = u.x + d[i][0]; v.y = u.y + d[i][1]; if (v.x < 0 || v.x >= n || v.y < 0 || v.y >= m || g[v.x][v.y] == '#') continue; if (v.x == e.x && v.y == e.y && bid[v.x][v.y] >= vis[u.x][u.y] + 1) { flag = 1; break; } if (bid[v.x][v.y] <= vis[u.x][u.y] + 1) continue; if (vis[v.x][v.y] > vis[u.x][u.y] + 1) { vis[v.x][v.y] = vis[u.x][u.y] + 1; Q.push(v); } } } printf("%s\n", flag ? "Yes" : "No"); } return 0; }
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 100005; typedef long long ll; int t, n; char str[N]; ll x, y; int one[N], zero[N], on, zn; ll sum[N], bit[N]; inline int lowbit(int x){ return x&(-x); } void add(int x, int v) { while (x <= n) { bit[x] += v; x += lowbit(x); } } ll get(int x) { ll ans = 0; while (x) { ans += bit[x]; x -= lowbit(x); } return ans; } int main() { scanf("%d", &t); while (t--) { scanf("%I64d%I64d", &x, &y); scanf("%s", str + 1); n = strlen(str + 1); memset(bit, 0, sizeof(bit)); on = zn = 0; ll tot = 0; ll sb = 0; for (int i = 1; i <= n; i++) { sum[i] = sum[i - 1]; if (str[i] == '1') { tot += sb; one[on++] = i; sum[i] += 1; } else { sb++; add(i, 1); } } for (int i = n; i >= 1; i--) if (str[i] == '0') zero[zn++] = i; ll ans = 0; while (on && zn && one[on - 1] > zero[zn - 1]) { if (x * tot < y + x * (tot - get(one[on - 1]) - (sum[one[on - 1] - 1] - sum[zero[zn - 1]]))) { ans += x * tot; break; } else { tot -= get(one[on - 1]) + (sum[one[on - 1] - 1] - sum[zero[zn - 1]]); add(zero[zn - 1], -1); zn--; on--; ans += y; } } printf("%I64d\n", ans); } return 0; }
标签:
原文地址:http://blog.csdn.net/accelerator_/article/details/45468987