正睿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 }
View Code

 

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 }
View Code

 

T3:

  暴力思路不对

T4:

  不会

T5:

  20pts暴力

总结:

  用set总是出问题,以后用set的时候还是要多看看会不会越界或空地址什么的

posted on 2020-10-25 20:17  ArrogHie  阅读(124)  评论(0编辑  收藏  举报