BZOJ 3123 SDOI 2013 森林 可持久化线段树+启发式合并
来源:互联网 发布:潘粤明 董洁 知乎 编辑:程序博客网 时间:2024/06/06 14:29
题目大意:给出一个森林,每个节点都有一个权值。有若干加边操作,问两点之间路径上的第k小权值是多少。
思路:这题和COT1比较像,但是多了连接操作。这样就只能暴力合并连个树。启发式合并会保证时间复杂度不至于太大。然后就是用可持久化线段树维护一个树的信息,按照dfs序来建树,每个节点的可持久化链的参考版本就是它父亲的版本。之后利用权值线段树可区间加减的特性,用f[x] + f[y] - f[lca] - f[father[lca]]来计算权值。
CODE:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 80010#define MAX_RANGE 1000000000#define POOL_SIZE 20000000using namespace std;struct PersSegTree{PersSegTree *son[2];int num;}mempool[POOL_SIZE],*C = mempool;int points,edges,asks;int src[MAX];int head[MAX],total;int next[MAX << 1],aim[MAX << 1];int f[MAX],cnt[MAX];int xx[MAX],top,father[MAX][20];int deep[MAX];PersSegTree *tree[MAX];char s[10];PersSegTree *NewNode(PersSegTree *_,PersSegTree *__,int ___){C->son[0] = _;C->son[1] = __;C->num = ___;return C++;}void Initialize(){for(int i = 1;i <= points; ++i)f[i] = i,cnt[i] = 1;tree[0] = NewNode(C,C,0);}inline void Add(int x,int y){next[++total] = head[x];aim[total] = y;head[x] = total;}int Find(int x){if(f[x] == x)return x;return f[x] = Find(f[x]);}void Unite(int x,int y){int fx = Find(x);int fy = Find(y);cnt[fx] += cnt[fy];f[fy] = fx;}void SparseTable(){for(int j = 1;j <= 19; ++j)for(int i = 1;i <= top; ++i)father[xx[i]][j] = father[father[xx[i]][j - 1]][j - 1];}int GetLCA(int x,int y){if(deep[x] < deep[y])swap(x,y);for(int i = 19; ~i; --i)if(deep[father[x][i]] >= deep[y])x = father[x][i];if(x == y)return x;for(int i = 19; ~i; --i)if(father[x][i] != father[y][i])x = father[x][i],y = father[y][i];return father[x][0];}PersSegTree *BuildTree(PersSegTree *consult,int l,int r,int val){if(l == r)return NewNode(NULL,NULL,consult->num + 1);int mid = (l + r) >> 1;if(val <= mid)return NewNode(BuildTree(consult->son[0],l,mid,val),consult->son[1],consult->num + 1);elsereturn NewNode(consult->son[0],BuildTree(consult->son[1],mid + 1,r,val),consult->num + 1);}void DFS(int x,int last){deep[x] = deep[last] + 1;father[x][0] = last;xx[++top] = x;tree[x] = BuildTree(tree[last],0,MAX_RANGE,src[x]);for(int i = head[x];i;i = next[i]) {if(aim[i] == last)continue;DFS(aim[i],x);}}int GetKth(PersSegTree *_l,PersSegTree *_r,PersSegTree *f,PersSegTree *p,int l,int r,int k){if(l == r)return l;int mid = (l + r) >> 1;int temp = _l->son[0]->num + _r->son[0]->num - f->son[0]->num - p->son[0]->num;if(k <= temp)return GetKth(_l->son[0],_r->son[0],f->son[0],p->son[0],l,mid,k);return GetKth(_l->son[1],_r->son[1],f->son[1],p->son[1],mid + 1,r,k - temp);}int main(){scanf("%*d%d%d%d",&points,&edges,&asks);Initialize();for(int i = 1;i <= points; ++i)scanf("%d",&src[i]);for(int x,y,i = 1;i <= edges; ++i) {scanf("%d%d",&x,&y);Add(x,y),Add(y,x);Unite(x,y);}for(int i = 1;i <= points; ++i)if(!deep[i])DFS(i,0);SparseTable();int last_ans = 0;for(int x,y,z,i = 1;i <= asks; ++i) {scanf("%s%d%d",s,&x,&y);x ^= last_ans,y ^= last_ans;if(s[0] == 'Q') {scanf("%d",&z);z ^= last_ans;int lca = GetLCA(x,y);printf("%d\n",last_ans = GetKth(tree[x],tree[y],tree[lca],tree[father[lca][0]],0,MAX_RANGE,z));}else {int fx = Find(x);int fy = Find(y);if(cnt[fx] > cnt[fy])swap(x,y);top = 0;DFS(x,y);Unite(x,y);Add(x,y),Add(y,x);SparseTable();}}return 0;}
0 0
- BZOJ 3123 SDOI 2013 森林 可持久化线段树+启发式合并
- BZOJ 3123 SDOI2013 森林 可持久化线段树+倍增LCA+启发式合并
- BZOJ 3123: [Sdoi2013]森林【可持久化值域线段树+启发式合并
- bzoj 3123: [Sdoi2013]森林 启发式合并+可持久化线段树
- [BZOJ3123][Sdoi2013]森林:可持久化线段树+启发式合并
- BZOJ 3123 森林 主席树启发式合并
- BZOJ 2733 [HNOI2012]永无乡 可持久化线段树合并
- Bzoj 3673: 可持久化并查集 by zky(主席树+启发式合并)
- hdu 6191 可持久化trie||线段树套trie||trie启发式合并
- BZOJ 3123 [Sdoi2013]森林 主席树+启发式合并
- BZOJ 3123: [Sdoi2013]森林|主席树|启发式合并
- [主席树 启发式合并] BZOJ 3123 [Sdoi2013]森林
- 【BZOJ 3123】[Sdoi2013]森林 启发式合并主席树
- Bzoj 3123: [Sdoi2013]森林(主席树+启发式合并)
- BZOJ 3123: [Sdoi2013]森林 启发式合并 树上主席树
- bzoj 2733 永无乡 线段树启发式合并
- BZOJ 2212 线段树启发式合并
- BZOJ 2653 可持久化线段树
- coursera Python交互编程入门 习题答案
- MyEclipse怎么自动生成注释
- 解决三星等设备video标签播放hls视频时候只有声音没有视频。。。
- 浏览器userAgent大全
- SQL Server UPDATE语句用于更新数据
- BZOJ 3123 SDOI 2013 森林 可持久化线段树+启发式合并
- ios android图设计
- Android开发之数据库Sqlite
- iOS - 音频播放简介
- jsp中的include和forward
- UserAgent的历史变迁
- 情报学的主要学术期刊
- Java核心技术卷I:基础知识(原书第8版):12.2 简单泛型类的定义
- Java继承、抽象、接口、多态