【主席树 启发式合并】bzoj3123: [Sdoi2013]森林
小细节磕磕碰碰浪费了半个多小时的时间
Description
Input
第一行包含一个正整数testcase,表示当前测试数据的测试点编号。保证1≤testcase≤20。
第二行包含三个整数N,M,T,分别表示节点数、初始边数、操作数。第三行包含N个非负整数表示 N个节点上的权值。
接下来 M行,每行包含两个整数x和 y,表示初始的时候,点x和点y 之间有一条无向边, 接下来 T行,每行描述一个操作,格式为“Q x y k”或者“L x y ”,其含义见题目描述部分。
Output
对于每一个第一类操作,输出一个非负整数表示答案。
HINT
对于第一个操作 Q 8 7 3,此时 lastans=0,所以真实操作为Q 8^0 7^0 3^0,也即Q 8 7 3。点8到点7的路径上一共有5个点,其权值为4 1 1 2 4。这些权值中,第三小的为 2,输出 2,lastans变为2。对于第二个操作 Q 3 5 1 ,此时lastans=2,所以真实操作为Q 3^2 5^2 1^2 ,也即Q 1 7 3。点1到点7的路径上一共有4个点,其权值为 1 1 2 4 。这些权值中,第三小的为2,输出2,lastans变为 2。之后的操作类似。
题目分析
这个题意已经是非常裸的数据结构题了。我们需要实现的有:只有加边的动态LCA、主席树启发式合并。
本来还想写个内存回收的,但是写完一来发现对效率好像不是很自信;二来看了看觉得空间也还过得去,就没再写回收了。
没有理解为什么森林初始不是全为点的。可能是为了区分我这样的大常数?
话说20s的题交上去刷新一下就返回TLE是什么机制……
- #include<bits/stdc++.h>
- const int maxn = ;
- const int maxm = ;
- const int maxNode = ;
- struct segNode
- {
- int l,r,val;
- }a[maxNode];
- struct Pool
- {
- int tot;
- int newNode()
- {
- ++tot, a[tot].l = a[tot].r = a[tot].val = ;
- return tot;
- }
- }node;
- char opt[];
- int T,n,m,q,lastans;
- int rt[maxn],c[maxn],tmp[maxn],fat[maxn],size[maxn];
- int edgeTot,head[maxn],nxt[maxm],edges[maxm];
- struct treeStruction
- {
- int fa[maxn][],dep[maxn];
- void init()
- {
- memset(fa, , sizeof fa);
- for (int i=; i<=n; i++) dep[i] = ;
- }
- int lca(int u, int v)
- {
- if (dep[u] < dep[v]) std::swap(u, v);
- for (int i=; i>=; i--)
- if (dep[fa[u][i]] >= dep[v]) u = fa[u][i];
- if (u==v) return u;
- for (int i=; i>=; i--)
- if (fa[u][i]!=fa[v][i])
- u = fa[u][i], v = fa[v][i];
- return fa[u][];
- }
- }tre;
- int read()
- {
- char ch = getchar();
- int num = , fl = ;
- for (; !isdigit(ch); ch=getchar())
- if (ch=='-') fl = -;
- for (; isdigit(ch); ch=getchar())
- num = (num<<)+(num<<)+ch-;
- return num*fl;
- }
- int find(int x)
- {
- while (x!=fat[x]) x = fat[x];
- return x;
- }
- void update(int &rt, int pre, int L, int R, int c)
- {
- rt = node.newNode();
- a[rt] = a[pre], ++a[rt].val;
- if (L==R) return;
- int mid = (L+R)>>;
- if (c <= mid) update(a[rt].l, a[pre].l, L, mid, c);
- else update(a[rt].r, a[pre].r, mid+, R, c);
- }
- int query(int u, int v, int lca, int fa, int L, int R, int k)
- {
- if (L==R) return L;
- int mid = (L+R)>>, val = a[a[u].l].val+a[a[v].l].val-a[a[lca].l].val-a[a[fa].l].val;
- if (k <= val) return query(a[u].l, a[v].l, a[lca].l, a[fa].l, L, mid, k);
- return query(a[u].r, a[v].r, a[lca].r, a[fa].r, mid+, R, k-val);
- }
- void connect(int x, int fat)
- {
- tre.dep[x] = tre.dep[fat]+, tre.fa[x][] = fat;
- update(rt[x], rt[fat], , tmp[], c[x]);
- for (int i=; i<=; i++)
- tre.fa[x][i] = tre.fa[tre.fa[x][i-]][i-];
- for (int i=head[x]; i!=-; i=nxt[i])
- if (fat!=edges[i]) connect(edges[i], x);
- }
- void addedge(int u, int v)
- {
- int fu = find(u), fv = find(v);
- if (size[fu] > size[fv]) std::swap(fu, fv), std::swap(u, v);
- fat[fu] = fv, size[fv] += size[fu], connect(u, v);
- edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
- edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
- }
- void discretization()
- {
- std::sort(tmp+, tmp+n+);
- tmp[] = std::unique(tmp+, tmp+n+)-tmp-;
- for (int i=; i<=n; i++)
- {
- c[i] = std::lower_bound(tmp+, tmp+tmp[]+, c[i])-tmp;
- update(rt[i], , , tmp[], c[i]);
- }
- }
- int main()
- {
- T = read();
- memset(rt, , sizeof rt);
- memset(head, -, sizeof head);
- n = read(), m = read(), q = read();
- tre.init();
- node.tot = lastans = edgeTot = ;
- for (int i=; i<=n; i++)
- tmp[i] = c[i] = read(), fat[i] = i, size[i] = ;
- discretization();
- for (int i=; i<=m; i++) addedge(read(), read());
- for (int i=; i<=q; i++)
- {
- scanf("%s",opt);
- if (opt[]=='Q'){
- int u = read()^lastans, v = read()^lastans;
- int k = read()^lastans, lca = tre.lca(u, v);
- lastans = tmp[query(rt[u], rt[v], rt[lca], rt[tre.fa[lca][]], , tmp[], k)];
- printf("%d\n",lastans);
- }else addedge(read()^lastans, read()^lastans);
- }
- return ;
- }
END
【主席树 启发式合并】bzoj3123: [Sdoi2013]森林的更多相关文章
- [bzoj3123] [SDOI2013]森林 主席树+启发式合并+LCT
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- 【bzoj3123】[Sdoi2013]森林 倍增LCA+主席树+启发式合并
题目描述 输入 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负 ...
- P3302 [SDOI2013]森林(主席树+启发式合并)
P3302 [SDOI2013]森林 主席树+启发式合并 (我以前的主席树板子是错的.......坑了我老久TAT) 第k小问题显然是主席树. 我们对每个点维护一棵包含其子树所有节点的主席树 询问(x ...
- 【BZOJ-3123】森林 主席树 + 启发式合并
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2738 Solved: 806[Submit][Status] ...
- BZOJ_3123_[Sdoi2013]森林_主席树+启发式合并
BZOJ_3123_[Sdoi2013]森林_主席树+启发式合并 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20 ...
- Bzoj 3123: [Sdoi2013]森林(主席树+启发式合并)
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当前 ...
- Bzoj2534:后缀自动机 主席树启发式合并
国际惯例的题面:考虑我们求解出字符串uvu第一个u的右端点为i,第二个u的右端点为j,我们需要满足什么性质?显然j>i+L,因为我们选择的串不能是空串.另外考虑i和j的最长公共前缀(也就是说其p ...
- 【主席树启发式合并】【P3302】[SDOI2013]森林
Description 给定一个 \(n\) 个节点的森林,有 \(Q\) 次操作,每次要么将森林中某两点联通,保证操作后还是个森林,要么查询两点间权值第 \(k\) 小,保证两点联通.强制在线. L ...
- Bzoj 3673: 可持久化并查集 by zky(主席树+启发式合并)
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Description n个集合 m个操作 操作: 1 a b 合并a,b所在集 ...
随机推荐
- ios 适配问题
两张图解决
- ESQL 查询数据报 参数类型“Edm.Decimal”和“Edm.Double”不兼容
ESQL 查询数据报 参数类型“Edm.Decimal”和“Edm.Double”不兼容 System.Data.Entity.Core.Objects.ObjectQuery<TEntity& ...
- centos 创建 logrotate 进行日志分割
这里就不赘述logrotate了,具体是什么,有什么作用,自行百度. 我们先说下,如何进行nginx的日志切割: 比如:日志目录为:/usr/local/nginx/logs/access.log按照 ...
- SWT的基本组件使用
1按钮组件(Button) (1)Button组件常用样式 SWT.PUSH按钮 SWT.CHECK多选按钮 SWT.RADIO单选按钮 SWT.ARROW箭头按钮 SWT.NONE默认按钮 SWT. ...
- hdu5709Claris Loves Painting主席树 奇妙的DFS序
先不考虑层数限制 一棵树上每个点有个颜色,问一棵子树的颜色数 感觉简单多了是吧 考虑每个点的贡献:自己到根的路径上的一个包含自己的连续段 观察最顶端的点的父亲: 它满足有了额外的同色孩子(咦) 这一条 ...
- docker安装软件
镜像相关命令 1.搜索镜像 # docker search java 可使用 docker search命令搜索存放在 Docker Hub(这是docker官方提供的存放所有docker镜像软件的地 ...
- 复习KMP
KMP刚学的时候,看不懂. 再看,哇!原来是这样! 用的时候,忘了. 为了不再跌倒,我决定,记住吧... 在我看来,KMP一般用于字符串匹配时的防超时优化. 他的精髓就是,利用已经匹配的信息,简化这之 ...
- 老技术,UrlRewriter实现全站伪静态
看人家做淘宝客很火,就做了个网站.seo的话当然需要全站伪静态了,问了下空间商不支持mvc,尼玛,好吧,isapi_rewrite支持吗?“额,不支持!” -_-! 额,好吧,搬出n年前的东西了:微软 ...
- 通过Maven构建打包Spring boot,并将config配置文件提取到jar文件外
如果通过不同的IDE打包,着实会觉得依赖性太大,并且容易出现错误,操作也比较复杂 同时,spring-boot-maven-plugin的使用感觉,相关配置太少,并且无法满足方便部署和运行的需求. 这 ...
- Echarts获取数据绘制图表
这次是利用mui框架实现一个手机移动端的项目.基本的框架已经实现,主要来获取数据实现一个图表的展示. 首先引入插件:echarts.js <script src="../resourc ...