Educational Codeforces Round 72 (Rated for Div. 2)
这个题目卡了我挺久的,这个有一个条件没有考虑到,就是这个最大只有exp+1
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> #include <map> #include <vector> #include <iostream> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; typedef long long ll; const int mx = 1e6 + 10; const int maxn = 1e5 + 10; int main() { int t; scanf("%d", &t); while (t--) { ll a, b, c; cin >> a >> b >> c; ll sum = a + b + c; sum = (sum - 1) >> 1ll; ll ans = sum - b + 1; ans = max(0*1ll, ans); cout << min(ans, c + 1) << endl; } return 0; }
这个题目和之前的A差不多,有些临界条件要考虑
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> #include <map> #include <vector> #include <iostream> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; typedef long long ll; const int mx = 1e6 + 10; const int maxn = 1e5 + 10; int main() { int t; scanf("%d", &t); while (t--) { ll n, x, maxs = 0, ans = 0; scanf("%lld%lld", &n, &x); for (int i = 1; i <= n; i++) { ll d, h; scanf("%lld%lld", &d, &h); maxs = max(maxs, d); ans = max(ans, d - h); } if (maxs >= x) { printf("1\n"); continue; } if (ans == 0) { if (maxs < x) printf("-1\n"); continue; } ll num = (x - maxs + ans - 1) / ans + 1; printf("%lld\n", num); } return 0; }
C. The Number Of Good Substrings
这个题目就是求一下每一个1和这个1前面0的个数。
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> #include <map> #include <vector> #include <iostream> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; typedef long long ll; const int maxn = 2e5 + 10; char s[maxn]; ll vis[maxn], pos[maxn]; int main() { int t; scanf("%d", &t); while(t--) { scanf("%s", s); ll len = strlen(s), cnt = 0, tot = 0; memset(vis, 0, sizeof(vis)); for(int i=0;i<len;i++) { if (s[i] == '0') cnt++; else { vis[++tot] = cnt; pos[tot] = i; cnt = 0; } } ll ans = 0; for(int i=1;i<=tot;i++) { ll res = 0, num = 0; for (int j = pos[i]; j < len; j++) { res = res * 2 + s[j] - '0'; num++; if (res - num <= vis[i]) ans++; else break; } } printf("%lld\n", ans); } return 0; }
题目大意是:
给你一个有向图,然后问这个图每一个循环都至少有两种颜色,最少要用多少种颜色。
这个是给边染色,因为没有重边和自循环,
每一个环的构成是肯定有从数值小的顶点到数值比较大的顶点,所以我们对于每一个边的染色。
只要把从数值小的指向数值大的都染成1,数值大的指向数值小的染成2就可以了。
这个一个环里面肯定至少有两种颜色,因为每一条边都是只会被染一次,所以肯定没有矛盾。
但是把染边改成染点,这个该怎么写呢?不太会。。。
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> #include <map> #include <vector> #include <iostream> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; typedef long long ll; const int maxn = 2e5 + 10; vector<int>G[maxn]; int d[maxn], n, m; void add(int u, int v) { G[u].push_back(v); d[v]++; } struct node { int u, v; node(int u=0,int v=0):u(u),v(v){} }ex[maxn]; bool tp() { int cnt = 0; queue<int>que; for (int i = 1; i <= n; i++) { if (d[i] == 0) que.push(i); } while (!que.empty()) { int u = que.front(); que.pop(); cnt++; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; d[v]--; if (d[v] == 0) que.push(v); } } if (cnt == n) return 0; return 1; } int main() { memset(d, 0, sizeof(d)); scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); add(u, v); ex[i] = node(u, v); } int f = tp(); if (f) { printf("2\n"); for (int i = 1; i <= m; i++) { if (ex[i].u < ex[i].v) printf("1 "); else printf("2 "); } printf("\n"); } else { printf("1\n"); for (int i = 1; i <= m; i++) printf("1 "); printf("\n"); } return 0; }
这个是一个比较简单的线段树,思路出的很快,但是写的有点搓。
我一开始建了两棵线段树,后来发现可以只建一颗,建两棵线段树的复杂度有点高,加了快读和快输卡着时间过去的。
然后删了一颗线段树之后,大概也要1000多ms,可能是我的这个写法时间复杂度偏高,我是记录了最小和次小值,然后query求一个区间的最小和次小值。
lj是直接用数组记录了一个区间的最小和次小值之和,然后再记录一个区间的最小值,这个是方便区间合并的时候用。
这个时间复杂度就比较低大概是500ms左右。
#include <cstdio> #include <cstdlib> #include <algorithm> #include <map> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; typedef long long ll; const int maxn = 2e5 + 5; int mins[10][maxn * 4], nmins[10][maxn * 4]; int n, m; inline int read() { int X = 0; bool flag = 1; char ch = getchar(); while (ch<'0' || ch>'9') { if (ch == '-') flag = 0; ch = getchar(); } while (ch >= '0'&&ch <= '9') { X = (X << 1) + (X << 3) + ch - '0'; ch = getchar(); } if (flag) return X; return ~(X - 1); } inline void write(int X) { if (X < 0) { putchar('-'); X = ~(X - 1); } int s[20], top = 0; while (X) { s[++top] = X % 10; X /= 10; } if (!top) s[++top] = 0; while (top) putchar(s[top--] + '0'); putchar('\n'); } void update2(int i, int id, int l, int r, int pos, int val) { // printf("i=%d id=%d l=%d r=%d pos=%d val=%lld\n", i, id, l, r, pos, val); if (l == r) { mins[i][id] = val; nmins[i][id] = inf * 2; return; } int mid = (l + r) >> 1; if (pos <= mid) update2(i, id << 1, l, mid, pos, val); else update2(i, id << 1 | 1, mid + 1, r, pos, val); mins[i][id] = min(mins[i][id << 1], mins[i][id << 1 | 1]); nmins[i][id] = min(min(nmins[i][id << 1], nmins[i][id << 1 | 1]), max(mins[i][id << 1], mins[i][id << 1 | 1])); } int ans1, ans2; void query2(int i, int id, int l, int r, int x, int y) { // printf("i=%d id=%d l=%d r=%d x=%d y=%d\n", i, id, l, r, x, y); if (x <= l && y >= r) { // printf("ans1=%lld ans2=%lld mins[%d][%d]=%lld\n", ans1, ans2, i, id, mins[i][id]); if (ans1 > mins[i][id]) { ans2 = ans1; ans1 = mins[i][id]; } else if (ans2 > mins[i][id]) ans2 = mins[i][id]; ans2 = min(ans2, nmins[i][id]); // printf("ans1=%lld ans2=%lld\n", ans1, ans2); return; } int mid = (l + r) >> 1; if (x <= mid) query2(i, id << 1, l, mid, x, y); if (y > mid) query2(i, id << 1 | 1, mid + 1, r, x, y); } void build(int i,int id,int l,int r) { mins[i][id] = nmins[i][id] = inf * 2; if(l==r) return; int mid = (l + r) >> 1; build(i, id << 1, l, mid); build(i, id << 1 | 1, mid + 1, r); } int main() { n = read(), m = read(); for (int i = 0; i < 10; i++) build(i, 1, 1, n); for (int i = 1; i <= n; i++) { int x, w; x=read(),w = x; for (int j = 0; j < 10; j++) { int val = x % 10; x /= 10; if(val) update2(j, 1, 1, n, i, w); else update2(j, 1, 1, n, i, inf * 2); } } while (m--) { int opt, x, y; opt = read(), x = read(), y = read(); if (opt == 1) { int w = y; for (int i = 0; i < 10; i++) { int val = y % 10; y /= 10; if (val) update2(i, 1, 1, n, x, w); else update2(i, 1, 1, n, x, inf * 2); } } else { int ans = inf * 2; for (int i = 0; i < 10; i++) { ans1 = ans2 = inf * 2; query2(i, 1, 1, n, x, y); ans = min(ans*1ll, ans1*1ll + ans2); } if (ans >= inf * 2) write(-1); else write(ans); } } return 0; }