正睿20秋季普转提day5
估分:10+100+40+0+20=170
实际:10+30+0+0+20=60
T1:
正解想到了,但是最后才倒回来做的,时间不够,没有调完
可以发现a一定是偶数,若a[i]=a[i-1],那么p[i]=i,如果a[i]-a[i-1]=2,那么就把i放到候选的栈里,如果a[i]-a[i-1]=-2,那就把候选栈顶的数取出来,假设是j,那么p[i]=j,p[j]=i。
因为这可以看作是若a[i]-a[i-1]=2那说明有一个覆盖区间的左端点在i,若a[i]-a[i-1]=-2那说明有一个覆盖的区间的右端点在i
1 #include<cstdio> 2 #include<cstring> 3 #include<stack> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 const int N = 200010; 9 10 int n; 11 int a[N], p[N]; 12 stack<int> stk; 13 14 inline int read() 15 { 16 int x = 0, f = 0; 17 char ch = getchar(); 18 while (!isdigit(ch)) f = ch == '-', ch = getchar(); 19 while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); 20 return f ? -x : x; 21 } 22 23 int main() 24 { 25 n = read(); 26 for (int i = 1; i < n; i++) a[i] = read(); 27 for (int i = 1; i <= n; i++) 28 { 29 if (a[i] == a[i - 1]) p[i] = i; 30 else if (a[i] == a[i - 1] + 2) stk.push(i); 31 else if (a[i] == a[i - 1] - 2) 32 { 33 int x = stk.top(); 34 stk.pop(); 35 p[x] = i, p[i] = x; 36 } 37 else puts("No"), exit(0); 38 } 39 puts("Yes"); 40 for (int i = 1; i <= n; i++) printf("%d ", p[i]); 41 }
T2:
用了set,然后他越界了
把颜色一样的缩点,然后每次操作相当于一个点把他连着的点合并为一个点,所以求缩点后的树的直径除二就行了
1 #include<cstdio> 2 #include<cstring> 3 #include<set> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 inline int read() 9 { 10 int x = 0, f = 0; 11 char ch = getchar(); 12 while (!isdigit(ch)) f = ch == '-', ch = getchar(); 13 while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); 14 return f ? -x : x; 15 } 16 17 const int N = 500010; 18 19 int n; 20 int col[N], fa[N], bel[N], dis[N], cnt; 21 int h[N], num[N << 1], nex[N << 1], dqx; 22 23 struct Edge 24 { 25 int a, b; 26 Edge() {} 27 Edge(int a, int b) :a(a), b(b) {} 28 }; 29 30 Edge edge[N << 1]; 31 32 int find1(int x) { return fa[x] == x ? x : fa[x] = find1(fa[x]); } 33 34 inline void add(int a, int b) 35 { 36 num[dqx] = b; 37 nex[dqx] = h[a]; 38 h[a] = dqx++; 39 } 40 41 void dfs(int u, int pa) 42 { 43 for (int i = h[u]; ~i; i = nex[i]) 44 { 45 int j = num[i]; 46 if (j == pa) continue; 47 if (col[j] != col[u]) bel[j] = ++cnt; 48 else bel[j] = bel[u]; 49 dfs(j, u); 50 } 51 } 52 53 void dfs1(int u, int pa) 54 { 55 for (int i = h[u]; ~i; i = nex[i]) 56 { 57 int j = num[i]; 58 if (j == pa) continue; 59 dis[j] = dis[u] + 1; 60 dfs1(j, u); 61 } 62 } 63 64 int main() 65 { 66 n = read(); 67 for (int i = 1; i <= n; i++) col[i] = read(); 68 memset(h, -1, sizeof(h)); 69 for (int i = 1; i < n; i++) 70 { 71 int a = read(), b = read(); 72 edge[i] = Edge(a, b); 73 add(a, b), add(b, a); 74 } 75 76 bel[1] = ++cnt; 77 dfs(1, 0); 78 79 dqx = 0; 80 memset(h, -1, sizeof(h)); 81 for (int i = 1; i <= cnt; i++) fa[i] = i; 82 for (int i = 1; i < n; i++) 83 { 84 int a = bel[edge[i].a], b = bel[edge[i].b]; 85 int a1 = find1(a), b1 = find1(b); 86 if (a1 == b1) continue; 87 add(a, b), add(b, a); 88 fa[a1] = b1; 89 } 90 91 dis[1] = 1; 92 dfs1(1, 0); 93 int u = 0; 94 for (int i = 1; i <= cnt; i++) if (dis[i] > dis[u]) u = i; 95 dis[u] = 1; 96 dfs1(u, 0); 97 int res = 0; 98 for (int i = 1; i <= cnt; i++) res = max(res, dis[i]); 99 printf("%d", res / 2); 100 }
T3:
暴力思路不对
T4:
不会
T5:
20pts暴力
总结:
用set总是出问题,以后用set的时候还是要多看看会不会越界或空地址什么的