正睿20秋季提高十连测day5
估分:75+23=98
实际:75+23=98
T1:
思路对了,但少考虑了二分图和不连通图的情况
连通图中,k=0,每个点度数必须为偶,k≥1,每个点度数可以全为偶或全为奇,k≥2,每个点度数可以全为偶或全为奇,若图为二分图还可以每条边都是两端端点一个为奇一个为偶。特别判断一条链的情况,k若大于等于边数,也是满足的(因为可以变为单点或空图)。
非连通图中,只有一个连通块可以不是一条链,其他连通块必须全部为链或单个点,且k能够把其他为链或单点的连通块全变成空图。之后把不是一条链的连通块当连通图考虑。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 inline int read() 8 { 9 int f = 0, x = 0; 10 char ch = getchar(); 11 while (!isdigit(ch)) f = ch == '-', ch = getchar(); 12 while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); 13 return f ? -x : x; 14 } 15 16 const int N = 1000010; 17 18 int n, m, k; 19 int u[N], v[N], sz[N], din[N], fa[N], e[N]; 20 21 int find(int x) 22 { 23 return x == fa[x] ? x : fa[x] = find(fa[x]); 24 } 25 26 int main() 27 { 28 n = read(), m = read(), k = read(); 29 30 for (int i = 1; i <= n; i++) fa[i] = i, sz[i] = 1; 31 32 for (int i = 1; i <= m; i++) 33 { 34 int a = read(), b = read(); 35 u[i] = a, v[i] = b; 36 din[a]++, din[b]++; 37 a = find(a), b = find(b); 38 if (a != b) fa[a] = b, sz[b] += sz[a], e[b] += e[a]; 39 e[b]++; 40 } 41 42 bool flag = 1, flag1 = 1, flag2 = 1; 43 int cnt = 0, cnt2 = 0; 44 for (int i = 1; i <= n; i++) 45 { 46 flag &= !(din[i] & 1); 47 if (i == find(i) && sz[i] == 1 && !k) 48 { 49 printf("No\n"); 50 return 0; 51 } 52 if (i == find(i) && sz[i] > 1 && (e[i] >= sz[i] || sz[i] > k)) 53 { 54 if (sz[i] == k + 1) 55 { 56 cnt2++; 57 continue; 58 } 59 60 cnt++; 61 for (int j = 1; j <= m; j++) 62 { 63 flag2 &= ((din[u[i]] & 1) ^ (din[v[i]] & 1)); 64 } 65 } 66 } 67 for (int i = 1; i <= m; i++) flag1 &= !((din[u[i]] + din[v[i]]) & 1); 68 if (!cnt && cnt2 == 1 || (cnt == 1 && !cnt2 && (flag || k >= 1 && flag1 || k > 1 && flag2))) printf("Yes\n"); 69 else printf("No\n"); 70 }
T2:
不会,29分的暴力没写对
整体二分,用容斥算出被询问的矩形被多少矩形覆盖,然后用树状数组维护,具体看代码
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long LL; 8 9 inline int read() 10 { 11 int x = 0, f = 0; 12 char ch = getchar(); 13 while (!isdigit(ch)) f = ch == '-', ch = getchar(); 14 while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); 15 return f ? -x : x; 16 } 17 18 const int N = 200010; 19 const int INF = 2147483600; 20 21 int n, m; 22 23 struct Node 24 { 25 int x, y, id; 26 Node() {} 27 }; 28 29 bool cmpx(Node a, Node b) 30 { 31 return a.x < b.x; 32 } 33 34 int ans[N + 1], id[N + 1]; 35 int sum[N + 1]; 36 37 struct Count 38 { 39 Node d[2][N + 1], p[N + 1], q[N + 1]; 40 41 inline void add(int q, int id, int x, int y) 42 { 43 d[q][id].id = id; 44 d[q][id].x = x + n + 1; 45 d[q][id].y = y + n + 1; 46 return; 47 } 48 49 int c[N + 1]; 50 inline void mdf(int x, int d) 51 { 52 for (; x <= 2 * n + 2; x += (x & (-x))) c[x] += d; 53 } 54 55 inline int qry(int x) 56 { 57 int ret = 0; for (; x; x -= (x & (-x))) ret += c[x]; return ret; 58 } 59 60 inline void Move(int l, int r, int ql, int qr, int n) 61 { 62 int np = 0, nq = 0; 63 for (int i = l; i <= r; i++) p[++np] = d[0][i]; 64 for (int i = ql; i <= qr; i++) q[++nq] = d[1][id[i]]; 65 sort(p + 1, p + np + 1, cmpx); sort(q + 1, q + nq + 1, cmpx); 66 int now = 1; 67 for (int i = 1; i <= nq; i++) 68 { 69 while (now <= np && p[now].x < q[i].x) { mdf(p[now].y, 1); ++now; } 70 sum[q[i].id] += n * (now - 1 - qry(q[i].y - 1)); 71 } 72 for (int i = 1; i < now; i++) mdf(p[i].y, -1); 73 return; 74 } 75 }L, R, D, U; 76 77 int K[N + 1]; 78 int p[N + 1], q[N + 1]; 79 80 inline void divide(int l, int r, int ql, int qr) 81 { 82 if (ql > qr) return; 83 if (l == r) 84 { 85 for (int i = ql; i <= qr; i++) ans[id[i]] = l; 86 return; 87 } 88 int mid = (l + r) >> 1; 89 L.Move(l, mid, ql, qr, 1); 90 R.Move(l, mid, ql, qr, 1); 91 U.Move(l, mid, ql, qr, 1); 92 D.Move(l, mid, ql, qr, 1); 93 94 int np = 0, nq = 0; 95 for (int i = ql; i <= qr; i++) 96 { 97 if (K[id[i]] <= mid - sum[id[i]]) p[++np] = id[i]; 98 else q[++nq] = id[i]; 99 } 100 101 for (int i = ql; i <= ql + np - 1; i++) id[i] = p[i - ql + 1]; 102 for (int i = ql + np; i <= qr; i++) id[i] = q[i - ql - np + 1]; 103 int md = ql + np - 1; 104 L.Move(l, mid, ql, md, -1); 105 R.Move(l, mid, ql, md, -1); 106 U.Move(l, mid, ql, md, -1); 107 D.Move(l, mid, ql, md, -1); 108 divide(l, mid, ql, md); 109 divide(mid + 1, r, md + 1, qr); 110 } 111 112 int main() 113 { 114 n = read(); m = read(); 115 for (int i = 1; i <= n; i++) 116 { 117 int x1 = read(), y1 = read(), x2 = read(), y2 = read(); 118 L.add(0, i, x2, y2); 119 R.add(0, i, -x1, -y1); 120 U.add(0, i, -y1, x2); 121 D.add(0, i, y2, -x1); 122 } 123 for (int i = 1; i <= m; i++) 124 { 125 int x1 = read(), y1 = read(), x2 = read(), y2 = read(); 126 L.add(1, i, x1, y1); 127 R.add(1, i, -x2, -y2); 128 U.add(1, i, -y2, x1); 129 D.add(1, i, y1, -x2); 130 K[i] = read(); 131 } 132 133 for (int i = 1; i <= m; i++) id[i] = i; 134 divide(1, n + 1, 1, m); 135 for (int i = 1; i <= m; i++) 136 { 137 if (ans[i] <= n) printf("%d\n", ans[i]); 138 else puts("-1"); 139 } 140 }
T3:
尽力了,真不会。思路看不懂,代码也看不懂。
总结:
T1虽然想出思路了,但特殊的情况还是没有考虑到,以后还是要想仔细点;容斥不大会用,还要多刷题,关于这种图上的数学期望题做少了,不会,数学期望不太会算,要多做些题。
浙公网安备 33010602011771号