题意:给你一棵树,树上的每个节点都有树值,给m个查询,问以每个点u为根的子树下有多少种权值恰好出现k次。
分析:首先要对权值离散化,然后要将树形转换为线形,配上图:。然后按照右端点从小到大排序,离线操作:将每一个深度的权值分组到相同权值的cnt中,当sz == k时,用树状数组更新+1,表示在该深度已经存在k个相同的权值,如果>k,之前k个-2(-1是恢复原样,再-1是为下次做准备?),然后一个点的子树的答案就是 sum (r) - sum (l-1)。
当然,区间离线问题用莫队算法是很好做的。
收获:1. 离散化 2. DFS序,树形变线形 3. 离线操作 4. 莫队算法
代码(树状数组):
/************************************************* Author :Running_Time* Created Time :2015/9/10 星期四 19:15:22* File Name :I.cpp ************************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include
代码(莫队算法):
/************************************************* Author :Running_Time* Created Time :2015/9/10 星期四 19:15:22* File Name :I.cpp ************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include
Codeforces Round #136 (Div. 1) B. Little Elephant and Array
分析:估计这是上面那道题的母题(弱化版),直接套用就行了,现在稍微理解了树状数组的维护方法,配上图:
代码(树状数组):
/************************************************* Author :Running_Time* Created Time :2015/9/11 星期五 18:39:17* File Name :B.cpp ************************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include
代码(莫队):
/************************************************* Author :Running_Time* Created Time :2015/9/11 星期五 20:05:22* File Name :B_Modui.cpp ************************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include