博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CodeForces 375D Tree and Queries
阅读量:4637 次
发布时间:2019-06-09

本文共 4830 字,大约阅读时间需要 16 分钟。

传送门:

题意:

给你一颗有根树,树上每个节点都有其对应的颜色,有m次询问,每次问你以点v为父节点的子树内满足某种颜色的数量大于k的颜色一共有多少种

题解:

冷静分析,胡乱分析,询问次数这么多,但是并没有修改操作,倘若把询问离线下来就好了

可是询问问的是每个点的树

这个时候我们的dfs序就可以派上用场了

dfs序:"所谓DFS序, 就是DFS整棵树依次访问到的结点组成的序列"

"DFS序有一个很强的性质: 一颗子树的所有节点在DFS序内是连续的一段, 利用这个性质我们可以解决很多问题"

通过对树进行一次dfs序操作,我们可以得到每个点他的子树所在的一段区间,这样我们就可以得到每个询问在dfs序下询问的区间了,那么我们怎么统计区间内颜色数量大于k的种类数量呢?

由于我们得到了离线下来的询问区间,用莫队算法可以在O(nsqrt(n))的时间内得到所有询问的答案

由于每次询问是查询区间内颜色种类的数量之和,我们需要用一个区间求和,单点修改的数据结构来维护莫队时统计答案和修改操作,因此我们可以用树状数组或者线段树来维护

代码:

/** *        ┏┓    ┏┓ *        ┏┛┗━━━━━━━┛┗━━━┓ *        ┃       ┃   *        ┃   ━    ┃ *        ┃ >   < ┃ *        ┃       ┃ *        ┃... ⌒ ...  ┃ *        ┃       ┃ *        ┗━┓   ┏━┛ *          ┃   ┃ Code is far away from bug with the animal protecting           *          ┃   ┃   神兽保佑,代码无bug *          ┃   ┃            *          ┃   ┃         *          ┃   ┃ *          ┃   ┃            *          ┃   ┗━━━┓ *          ┃       ┣┓ *          ┃       ┏┛ *          ┗┓┓┏━┳┓┏┛ *           ┃┫┫ ┃┫┫ *           ┗┻┛ ┗┻┛ */// warm heart, wagging tail,and a smile just for you!////                            _ooOoo_//                           o8888888o//                           88" . "88//                           (| -_- |)//                           O\  =  /O//                        ____/`---'\____//                      .'  \|     |//  `.//                     /  \|||  :  |||//  \//                    /  _||||| -:- |||||-  \//                    |   | \\  -  /// |   |//                    | \_|  ''\---/''  |   |//                    \  .-\__  `-`  ___/-. ///                  ___`. .'  /--.--\  `. . __//               ."" '<  `.___\_<|>_/___.'  >'"".//              | | :  `- \`.;`\ _ /`;.`/ - ` : | |//              \  \ `-.   \_ __\ /__ _/   .-` /  ///         ======`-.____`-.___\_____/___.-`____.-'======//                            `=---='//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//                     佛祖保佑      永无BUG#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long LL;typedef pair
pLL;typedef pair
pLi;typedef pair
pil;;typedef pair
pii;typedef unsigned long long uLL;#define ls rt<<1#define rs rt<<1|1#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define bug printf("*********\n")#define FIN freopen("input.txt","r",stdin);#define FON freopen("output.txt","w+",stdout);#define IO ios::sync_with_stdio(false),cin.tie(0)#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<
<<"]\n"const double eps = 1e-8;const int mod = 1e9 + 7;const int maxn = 3e5 + 5;const int INF = 0x3f3f3f3f;const LL INFLL = 0x3f3f3f3f3f3f3f3f;struct EDGE { int v, nxt;} edge[maxn * 2];int head[maxn];int tot;void add_edge(int u, int v) { edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++;}int n, m;int col[maxn];int dfn[maxn], st[maxn], ed[maxn], cnt;int vis[maxn];int num[maxn];int bit[maxn];int ans[maxn];void dfs(int u, int fa, int depth) { st[u] = ++cnt; num[cnt] = col[u]; for(int i = head[u]; i != -1; i = edge[i].nxt) { int v = edge[i].v; if(v != fa) { dfs(v, u, depth + 1); } } ed[u] = cnt;}vector
vec[maxn];int v[maxn];int k[maxn];struct node { int l, r, id, k;} q[maxn];int pos[maxn];bool cmp(node a, node b) { if(pos[a.l] == pos[b.l]) return a.r < b.r; return pos[a.l] < pos[b.l];}int lowbit(int x) { return x & -x;}void update(int pos, int x) { if(pos <= 0) return; while(pos < maxn) { bit[pos] += x; pos += lowbit(pos); }}int query(int pos) { int ans = 0; while(pos) { ans += bit[pos]; pos -= lowbit(pos); } return ans;}void add(int x) { update(vis[num[x]], -1); vis[num[x]]++; update(vis[num[x]], 1);}void del(int x) { update(vis[num[x]], -1); vis[num[x]]--; update(vis[num[x]], 1);}int main() {#ifndef ONLINE_JUDGE FIN#endif scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%d", &col[i]); } memset(head, -1, sizeof(head)); tot = cnt = 0; for(int i = 1, u, v; i <= n - 1; i++) { scanf("%d%d", &u, &v); add_edge(u, v); add_edge(v, u); } dfs(1, 0, 1); int sz = sqrt(cnt); for(int i = 1; i <= cnt; i++) { pos[i] = i / sz; } for(int i = 1; i <= m; i++) { scanf("%d%d", &v[i], &k[i]); q[i].l = st[v[i]]; q[i].r = ed[v[i]]; q[i].id = i; q[i].k = k[i]; } sort(q + 1, q + m + 1, cmp); int L = 1, R = 0; for(int i = 1; i <= m; i++) { while(L < q[i].l) { L++; del(L - 1); } while(L > q[i].l) { add(L - 1); L--; } while(R < q[i].r) { R++; add(R); } while(R > q[i].r) { del(R); R--; } ans[q[i].id] = query(maxn - 1) - query(q[i].k - 1); } for(int i = 1; i <= m; i++) { printf("%d\n", ans[i]); } return 0;}

转载于:https://www.cnblogs.com/buerdepepeqi/p/10897505.html

你可能感兴趣的文章
泛型在三层中的应用
查看>>
SharePoint2010 -- 管理配置文件同步
查看>>
.Net MVC3中取得当前区域的名字(Area name)
查看>>
获得屏幕像素以及像素密度
查看>>
int与string转换
查看>>
adb命令 判断锁屏
查看>>
推荐一个MacOS苹果电脑系统解压缩软件
查看>>
1035等差数列末项计算
查看>>
CDMA鉴权
查看>>
ASP.NET MVC Identity 兩個多個連接字符串問題解決一例
查看>>
过滤器与拦截器区别
查看>>
USACO 1.5.4 Checker Challenge
查看>>
第二阶段站立会议7
查看>>
[18]Debian Linux Install GNU GCC Compiler and Development Environment
查看>>
JAVA多线程
查看>>
ACE(Adaptive Communication Environment)介绍
查看>>
delphi 更改DBGrid 颜色技巧
查看>>
python编码问题
查看>>
POJ 2031 Building a Space Station
查看>>
面向对象1
查看>>