2014网络赛 hdu 5029 树链剖分 + 线段树
来源:互联网 发布:大卫杜夫冷水 知乎 编辑:程序博客网 时间:2024/06/06 14:19
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5029
题意:RT
先搞定一维的情况。
一维的问题就是给m个操作,每个操作给一个L,R,C,表示区间[L,R]增加一种颜色C。问最后每个点最多的颜色是什么。对于每个L,R C我们可以在L这个时刻在C这个点加一,在R+1这个点减一。这样将所有区间分成两个点L,R+1 将所有点按左到右排序。然后从左到右处理每个点。当处理到当前点i的时候。将区间那些点用线段树更新完,查询一下哪种最多就是了。
一维的解决完,二维的用树链剖分搞定将树链划分成logn个连续区间。然后对于划分后的区间就是一维的问题了。然后还原一下就ok。注意这里是点的修改,不是线段修改。
代码如下:
#include <iostream>#include <cstdio>#include <cstring>#include <iostream>#include <queue>#include <algorithm>#define lson L,mid,lc#define rson mid + 1,R,rc#define root 1,n,1using namespace std;const int N = 2000005;int eh[N],cnt,num,ans[N],re[N];struct Edge{ int from,to,next; Edge(){} Edge(int u,int v,int n):from(u),to(v),next(n){}}edge[N];struct cc{ int v,id,val; bool operator <(const cc &s)const{ return id < s.id; }}ar[N];inline void add(int u,int v,int n){ edge[cnt] = Edge(u,v,n);}void addedge(int u,int v){ add(u,v,eh[u]); eh[u] = cnt++; add(v,u,eh[v]); eh[v] = cnt++;}int fa[N],son[N],w[N],siz[N],dep[N],tot,top[N];void dfs1(int u,int d){ dep[u] = d; int maxn = 0,id = 0,sum = 1; for(int i = eh[u];i != -1;i = edge[i].next) { int v = edge[i].to; if(v == fa[u])continue; fa[v] = u; dfs1(v,d + 1); sum += siz[v]; if(siz[v] > maxn){maxn = siz[v],id = v;} } son[u] = id;siz[u] = sum;}void dfs2(int u){ re[++tot] = u; w[u] = tot; if(!top[u]) top[u] = u; if(son[u]) { top[son[u]] = top[u]; dfs2(son[u]); } for(int i = eh[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v == fa[u] || v == son[u]) continue; dfs2(v); }}void init(){ memset(eh,-1,sizeof(eh)); memset(top,0,sizeof(top)); memset(son,0,sizeof(son)); memset(siz,0,sizeof(siz)); tot = cnt = num = 0;}void div(int L,int R,int z){ ++R; ar[num].v = ar[num + 1].v = z; ar[num].id = L;ar[num + 1].id = R; ar[num++].val = 1;ar[num++].val = -1;}void find(int x,int y,int z){ int f1 = top[x],f2 = top[y]; while(f1 != f2) { if (dep[f1] < dep[f2]){swap(f1, f2); swap(x, y);} div(w[f1],w[x],z); x = fa[f1]; f1 = top[x]; } if (dep[x] > dep[y]) swap(x, y); div(w[x], w[y],z);}int c[N],maxn[N];void maintain(int lc,int rc,int o){ if(c[lc] == c[rc]){ if(maxn[lc] < maxn[rc]) { c[o] = c[lc];maxn[o] = maxn[lc];} else {c[o] = c[rc];maxn[o] = maxn[rc];} }else if(c[lc] > c[rc]){ c[o] = c[lc];maxn[o] = maxn[lc]; }else{ c[o] = c[rc];maxn[o] = maxn[rc]; } if(c[o] == 0) maxn[o] = 0;}void update(int L,int R,int o,int p,int v){ if(L == R){ c[o] += v; if(c[o]) maxn[o] = L; else maxn[o] = 0; return; } int mid = (L + R) >> 1; int lc = o << 1,rc = lc | 1; if(p <= mid) update(lson,p,v); else update(rson,p,v); maintain(lc,rc,o);}void solve(int kk,int m){ int n = 100002; memset(maxn,0,sizeof(maxn)); memset(c,0,sizeof(c)); sort(ar,ar + num); for(int i = 1,index = 0;i <= kk; ++i) { while(index < num && ar[index].id == i) { update(root,ar[index].v,ar[index].val); ++index; } ans[re[i]] = maxn[1]; } for(int i = 1; i <= kk; ++i) { printf("%d\n",ans[i]); }}int main(){ int n,m; while(~scanf("%d%d",&n,&m)) { if(n == 0 && m == 0) return 0; init(); for(int i = 1;i < n; ++i) { int u,v; scanf("%d%d",&u,&v); addedge(u,v); } dfs1(1,0); dfs2(1); for(int i = 0;i < m; ++i) { int x,y,z; scanf("%d%d%d",&x,&y,&z); find(x,y,z); } solve(n,m); } return 0;}
0 0
- 2014网络赛 hdu 5029 树链剖分 + 线段树
- HDU 5023 (2014广州网络赛 线段树)
- HDU 5052 Yaoge’s maximum profit(树链剖分+线段树,2014上海网络赛1011)
- hdu 5029树链剖分+线段树
- HDU 5493 Queue (线段树) 2015合肥网络赛
- HDU 5493 Queue (线段树)2015合肥赛区网络赛
- HDU 5875 Function 大连网络赛 线段树
- hdu 5493 线段树(2015年合肥网络赛)
- [hdu 5032]2014北京网络赛Always Cook Mushroom 离线线段树/树状数组
- [hdu 5032]2014北京网络赛Always Cook Mushroom 离线线段树/树状数组
- hdu 5029 Relief grain (树链剖分+线段树)
- hdu 5029 Relief grain(树链剖分+线段树)
- HDU 5029Relief grain(树链剖分+线段树)
- hdu 3966 (树链剖分+线段树)
- hdu 3804(树链剖分+线段树)
- hdu 3804 树链剖分+线段树
- hdu 3966 树链剖分+线段树
- HDU 4288 Coder(12年成都网络赛-A题-离线 + 线段树)
- 为什么两次调用同一函数, 输入相同, 输出却不同呢? (解决困扰自己好几天的问题, 还是有点激动哈, 奖励自己一顿丰厚的晚餐)
- javascript window.open详解
- OC 基础学习2
- Android消息处理机制——Looper,Handler,Message,MessageQueue
- Unique Binary Search Trees (leetcode)
- 2014网络赛 hdu 5029 树链剖分 + 线段树
- VIM代码补全提示功能
- org.hibernate.LazyInitializationException: could not initialize proxy - no Session
- strcat函数的实现
- nssting 编码问题
- 关键字之volatile
- Chapter 8 ARP 与 RARP
- 【google apec 2015 1b】problem d: 取第k个括号序列 卡特兰数/动态规划
- SpringMVC中简单的上传