2017 Multi-University Training Contest 第一场
2017-07-27 11:04
337 查看
题解在:http://bestcoder.hdu.edu.cn/blog/2017-multi-university-training-contest-8-solutions-by-%E5%8C%97%E4%BA%AC%E8%88%AA%E7%A9%BA%E8%88%AA%E5%A4%A9%E5%A4%A7%E5%AD%A6/#comment-42
四题200多名吧
反正就只能切水题
1001
求2^m次方有多少位,一开始以为是找规律,但发现有误差,后来发现用公式变成log可以直接算出来。
1002
很坑,wa了很多次。但是思路一开始就是对了,算出各个字母的贡献值,然后排序,不过一开始没注意前导0
1006
置换群,然后xzn写完,帮他查了很多弱智错误。。然后过了
1011
找规律 我们可以发现是 (n 1 2 3 4 … ..n-2) + (n-1 1 2 3 ….n-2)的循环节。
然后敲了一发,就过了。
补题:
1003
题意:一棵树中每个节点都有一个颜色,求所有路径的sum。
每条路径值 = 这条路径经过的颜色种数。
这个问题的路径其实是可以分割的,比赛时一直以为不可以分割,所以不会。
既然可以分割,必然也不需要去枚举路径。
比如
1
\
2
\
3
这样一棵树,颜色1 经过他的路径条数有2条
颜色2 经过他的路径条数有3条
颜色3经过他的路径条数有2条 所以ans=7
1
\
2
/ \
1 3
这样一棵树,颜色1 经过他的路径条数有2+3条
颜色2 经过他的路径条数有3+3条
颜色3经过他的路径条数有2+1条 所以ans=14
我们可以再列举几个例子,仔细想想,这个推断竟然是成立的,惊了!
再仔细想想,其实是有道理的,因为每条路径上的每种颜色对答案的贡献值其实是1
所以对于每一种颜色来说,贡献值就是有多少条路径通过这一种颜色。
但是统计这个是很有可能重复统计的,所以我们反过来思考,有多少条路径没有经过某种颜色
然后我们跑出dfs序 每一种颜色(可能有多个点) 会把树 划分成许多块。
然后我们那总路径数,减去这些不经过这种颜色的路径数。
然后我们再看标程,哇,写的是真的好,这是世界上最难学的算法就是dfs。
四题200多名吧
反正就只能切水题
1001
求2^m次方有多少位,一开始以为是找规律,但发现有误差,后来发现用公式变成log可以直接算出来。
1002
很坑,wa了很多次。但是思路一开始就是对了,算出各个字母的贡献值,然后排序,不过一开始没注意前导0
1006
置换群,然后xzn写完,帮他查了很多弱智错误。。然后过了
1011
找规律 我们可以发现是 (n 1 2 3 4 … ..n-2) + (n-1 1 2 3 ….n-2)的循环节。
然后敲了一发,就过了。
补题:
1003
题意:一棵树中每个节点都有一个颜色,求所有路径的sum。
每条路径值 = 这条路径经过的颜色种数。
这个问题的路径其实是可以分割的,比赛时一直以为不可以分割,所以不会。
既然可以分割,必然也不需要去枚举路径。
比如
1
\
2
\
3
这样一棵树,颜色1 经过他的路径条数有2条
颜色2 经过他的路径条数有3条
颜色3经过他的路径条数有2条 所以ans=7
1
\
2
/ \
1 3
这样一棵树,颜色1 经过他的路径条数有2+3条
颜色2 经过他的路径条数有3+3条
颜色3经过他的路径条数有2+1条 所以ans=14
我们可以再列举几个例子,仔细想想,这个推断竟然是成立的,惊了!
再仔细想想,其实是有道理的,因为每条路径上的每种颜色对答案的贡献值其实是1
所以对于每一种颜色来说,贡献值就是有多少条路径通过这一种颜色。
但是统计这个是很有可能重复统计的,所以我们反过来思考,有多少条路径没有经过某种颜色
然后我们跑出dfs序 每一种颜色(可能有多个点) 会把树 划分成许多块。
然后我们那总路径数,减去这些不经过这种颜色的路径数。
然后我们再看标程,哇,写的是真的好,这是世界上最难学的算法就是dfs。
typedef long long LL; const int maxn = 200001; int n, c[maxn], lnk[maxn], pos[maxn], ctr[maxn], rem[maxn]; //rem 存的是 当前节点所有子节点数 (当某颜色上面的节点没有当前颜色节点时,上面的所有节点块形成的每条路径不不经过这种颜色。 //ctr 存在的是下一个相同颜色节点 的 子节点个数。 LL ans; struct Edge { int nxt, v; } e[maxn << 1 | 1]; inline LL sum2(int x) { return (x * (x - 1LL)) >> 1; } int dfs(int u, int fa) { int su = 1, o = pos[c[u]]; // pos[c[u]] 当前颜色在dfs中上一个当前颜色的节点号 pos[c[u]] = u; // 颜色x的位置更新为u,当前的 for(int it = lnk[u]; it; it = e[it].nxt) // 遍历 if(e[it].v != fa) { ctr[u] = 0; // ctr 要初始化为0,不然dfs与u相同的颜色时会累加到ctr[u]上来 int sv = dfs(e[it].v, u); // e[it].v这一块子树的节点数。不包括u ans -= sum2(sv - ctr[u]); //(e[it].v这一块子树)所有子节点数-下一个相同颜色节点的子节点数= 他们之间的连通块的数目。 // 还有一个忽略的地方: 如果ctr[u]=0,那么说明下面没有相同颜色,所以下面的块形成的路径也应该减去。 su += sv; } // (o ? ctr[o] : rem[c[u]]) += su; /* 走到这一步时,dfs已经把u的所有的子树都扫过一遍了。 如果o为真,代表前面最近出现c[u],节点号为o,且o 不可能是子树中出现的 所以此时,当前节点 的所有子节点数(包括自己) 都加到 上一个节点o的ctr 中 */ if(o) ctr[o]+=su; // else rem[c[u]]+=su; //如果上面没出现过, 那么他所有的子树放进rem[当前颜色](把自己也放进去) pos[c[u]] = o; // 还原当前颜色的节点号,所以每一个的o 都必然是上面最近的颜色x的位置。 return su; //返回包括自己+所有子树的节点数 } int main() { //freopen("1.txt","r",stdin); for(int Case = 1; scanf("%d", &n) == 1; ++Case) { for(int i = 1; i <= n; ++i) { scanf("%d", c + i); lnk[i] = rem[i] = 0; } for(int i = 1, u, v; i < n; ++i) { scanf("%d%d", &u, &v); e[i << 1] = (Edge){lnk[u], v}; lnk[u] = i << 1; e[i << 1 | 1] = (Edge){lnk[v], u}; lnk[v] = i << 1 | 1; // 链式存图 } ans = sum2(n) * n; // 一共有n(n-1)/2条路径,假设每条路径都经过n? // printf("%I64d\n",ans); dfs(1, -1); // printf("%I64d\n",ans); for(int i = 1; i <= n; ++i) // 遍历所有节点 ans -= sum2(n - rem[i]); printf("Case #%d: %I64d\n", Case, ans); } return 0; }
相关文章推荐
- 2017 Multi-University Training Contest - 第一场 04 Division Game (NTT+数学)
- 【2017 Multi-University Training Contest - Team 1】小结
- 2017 Multi-University Training Contest - Team 1 1011&&HDU 6043 KazaQ's Socks【规律题,数学,水】
- hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)
- 2017 Multi-University Training Contest - Team 1 1002&&HDU 6034 Balala Power!【字符串,贪心+排序】
- hdu 6047 Maximum Sequence(2017 Multi-University Training Contest - Team 2)
- hdu 6045 Is Derek lying?(2017 Multi-University Training Contest - Team 2)
- 2017 Multi-University Training Contest - Team 2:1011 Regular polygon
- HDU 6040 - Hints of sd0061 | 2017 Multi-University Training Contest 1
- 2017 Multi-University Training Contest - Team 1 03Colorful Tree
- hdu 6055 Regular polygon(判断正方形)(2017 Multi-University Training Contest - Team 2)
- 2017 Multi-University Training Contest - Team 1:1003. Colorful Tree
- 【2017 Multi-University Training Contest - Team 7 && hdu 6121】Build a tree
- 【2017 Multi-University Training Contest - Team 5】Rikka with Graph
- 2017 Multi-University Training Contest - Team 3 1011 RXD's date
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- 2017 Multi-University Training Contest 3 1003/hdu6058
- 转载hdu 6059 字典树(好题要慢慢消化)2017 Multi-University Training Contest - Team 3
- 2017 Multi-University Training Contest - Team 3 :Kanade's sum
- hdu 6069 Counting Divisors(约数个数)(2017 Multi-University Training Contest - Team 4 )