【BZOJ-3123】森林 主席树 + 启发式合并
3123: [Sdoi2013]森林
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 2738 Solved: 806
[Submit][Status][Discuss]
Description
.jpg)
Input
第一行包含一个正整数testcase,表示当前测试数据的测试点编号。保证1≤testcase≤20。
第二行包含三个整数N,M,T,分别表示节点数、初始边数、操作数。第三行包含N个非负整数表示 N个节点上的权值。
接下来 M行,每行包含两个整数x和 y,表示初始的时候,点x和点y 之间有一条无向边, 接下来 T行,每行描述一个操作,格式为“Q x y k”或者“L x y ”,其含义见题目描述部分。
Output
对于每一个第一类操作,输出一个非负整数表示答案。
Sample Input
8 4 8
1 1 2 2 3 3 4 4
4 7
1 8
2 4
2 1
Q 8 7 3 Q 3 5 1
Q 10 0 0
L 5 4
L 3 2 L 0 7
Q 9 2 5 Q 6 1 6
Sample Output
2
1
4
2
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。之后的操作类似。
.jpg)
Source
Solution
沃日..这题什么东西..
直接树上主席树启发式合并就好了...
然后我写了3遍..第一遍2&10~13RE其余AC..然后肉眼差错无果..重写第二遍,基本没变,10~13RE...MD再写AC..什么破玩意...
我觉得唯一需要注意的就是LCA合并后要清空,还好我注意到了...
Code
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN 100010
int N,M,Q,ls[MAXN],top,val[MAXN],testcase,lastans;
struct EdgeNode{
int next,to;
}edge[MAXN<<1];
int head[MAXN],cnt=1;
inline void AddEdge(int u,int v) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v;}
inline void InsertEdge(int u,int v) {AddEdge(u,v); AddEdge(v,u);} namespace UF
{
int f[MAXN],size[MAXN];
inline void init() {for (int i=1; i<=N; i++) f[i]=i,size[i]=1;}
inline int F(int x) {if (x==f[x]) return x; return f[x]=F(f[x]);}
inline void Merge(int x,int y) {x=F(x),y=F(y); size[y]+=size[x]; f[x]=y;}
}using namespace UF;
namespace PrTree
{
int lson[MAXN*100],rson[MAXN*100],root[MAXN],sum[MAXN*100],sz;
inline void Insert(int l,int r,int &x,int y,int pos,int val)
{
x=++sz; sum[x]=sum[y]+val;
if (l==r) return;
lson[x]=lson[y],rson[x]=rson[y];
int mid=(l+r)>>1;
if (pos<=mid) Insert(l,mid,lson[x],lson[y],pos,val);
else Insert(mid+1,r,rson[x],rson[y],pos,val);
}
inline int Query(int l,int r,int kth,int a,int b,int c,int d)
{
if (l==r) return l;
int Sum=0,mid=(l+r)>>1;
Sum=sum[lson[a]]+sum[lson[b]]-sum[lson[c]]-sum[lson[d]];
if (Sum<kth)
return Query(mid+1,r,kth-Sum,rson[a],rson[b],rson[c],rson[d]);
else
return Query(l,mid,kth,lson[a],lson[b],lson[c],lson[d]);
}
}using namespace PrTree;
int deep[MAXN],father[18][MAXN];
inline void DFS(int now,int last)
{
PrTree::Insert(1,top,root[now],root[last],val[now],1);
for (int i=1; i<=17; i++)
if (deep[now]>=(1<<i))
father[i][now]=father[i-1][father[i-1][now]];
else father[i][now]=0;
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].to!=last)
{
deep[edge[i].to]=deep[now]+1;
father[0][edge[i].to]=now;
DFS(edge[i].to,now);
}
}
inline int LCA(int x,int y)
{
if (deep[x]<deep[y]) swap(x,y);
int dd=deep[x]-deep[y];
for (int i=0; i<=17; i++)
if (dd&(1<<i)) x=father[i][x];
for (int i=17; i>=0; i--)
if (father[i][x]!=father[i][y])
x=father[i][x],y=father[i][y];
return x==y? x:father[0][x];
}
inline void Link(int x,int y)
{
int fx=F(x),fy=F(y);
InsertEdge(x,y);
if (size[fx]>size[fy])
father[0][y]=x,deep[y]=deep[x]+1,DFS(y,x);
else
father[0][x]=y,deep[x]=deep[y]+1,DFS(x,y);
Merge(x,y);
}
int main()
{
// freopen("tree.in","r",stdin);
// freopen("tree.out","w",stdout);
testcase=read();
N=read(),M=read(),Q=read();
for (int i=1; i<=N; i++) ls[i]=val[i]=read();
sort(ls+1,ls+N+1); top=unique(ls+1,ls+N+1)-ls-1;
for (int i=1; i<=N; i++) val[i]=lower_bound(ls+1,ls+top+1,val[i])-ls; UF::init();
for (int i=1,x,y; i<=M; i++) x=read(),y=read(),InsertEdge(x,y),Merge(x,y); for (int i=1; i<=N; i++) if (!root[i]) DFS(i,0); while (Q--)
{
char opt[2]; scanf("%s",opt+1);
int x,y,z,lca;
switch (opt[1])
{
case 'Q':
x=read(),y=read(),z=read(); x^=lastans,y^=lastans,z^=lastans; lca=LCA(x,y);
printf("%d\n",lastans=ls[PrTree::Query(1,top,z,root[x],root[y],root[lca],root[father[0][lca]])]);
break;
case 'L':
x=read(),y=read(); x^=lastans,y^=lastans; Link(x,y);
break;
}
}
return 0;
}
【BZOJ-3123】森林 主席树 + 启发式合并的更多相关文章
- Bzoj 3123: [Sdoi2013]森林(主席树+启发式合并)
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当前 ...
- [bzoj3123] [SDOI2013]森林 主席树+启发式合并+LCT
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- BZOJ 3123: [Sdoi2013]森林 [主席树启发式合并]
3123: [Sdoi2013]森林 题意:一个森林,加边,询问路径上k小值.保证任意时刻是森林 LCT没法搞,树上kth肯定要用树上主席树 加边?启发式合并就好了,小的树dfs重建一下 注意 测试点 ...
- 【BZOJ 3123】 [Sdoi2013]森林 主席树启发式合并
我们直接按父子关系建主席树,然后记录倍增方便以后求LCA,同时用并查集维护根节点,而且还要记录根节点对应的size,用来对其启发式合并,然后每当我们合并的时候我们都要暴力拆小的一部分重复以上部分,总时 ...
- [BZOJ3123][Sdoi2013]森林 主席树+启发式合并
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当 ...
- luoguP3302 [SDOI2013]森林 主席树 启发式合并
题目链接 luoguP3302 [SDOI2013]森林 题解 本来这题树上主席树暴力启发式合并就完了 结果把lca写错了... 以后再也不这么写了 复杂度\(O(nlog^2n)\) "f ...
- [SDOI2013]森林 主席树+启发式合并
这题的想法真的很妙啊. 看到题的第一眼,我先想到树链剖分,并把\(DFS\)序当成一段区间上主席树.但是会发现在询问的时候,可能会非常复杂,因为你需要把路径拆成很多条轻链和重链,它们还不一定连续,很难 ...
- P3302 [SDOI2013]森林(主席树+启发式合并)
P3302 [SDOI2013]森林 主席树+启发式合并 (我以前的主席树板子是错的.......坑了我老久TAT) 第k小问题显然是主席树. 我们对每个点维护一棵包含其子树所有节点的主席树 询问(x ...
- 【主席树 启发式合并】bzoj3123: [Sdoi2013]森林
小细节磕磕碰碰浪费了半个多小时的时间 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M ...
随机推荐
- 使用solr批量导入mysql数据库,以及Unable to read: dataimport.properties等坑
折腾了一下午终于成功了!先放一张成功图: 成功把mysql的数据添加进去了,我这里是整合了tomcat9,整合步骤挺麻烦的,百度一大堆! 这里主要介绍批量导入数据,这里有些坑,所以记录一下: 步骤: ...
- C/C++杂记:NULL与0的区别、nullptr的来历
某些时候,我们需要将指针赋值为空指针,以防止野指针. 有人喜欢使用NULL作为空指针常量使用,例如:int* p = NULL;. 也有人直接使用0值作为空指针常量,例如:int* p = 0;. ...
- 解决eclipse Debug时提示source not found的问题
解决办法: 选择Change Attached Source,添加自己的project,clean项目,重启eclipse即可.
- MongoDB的安装与使用
MongoDB是一款NoSql数据库.NoSql数据库叫非关系型数据库,NoSql的全名Not only sql.是为了解决高并发.高可用.高可扩展,以及大数据存储等一系列问题而产生的数据库解决方案. ...
- Hadoop(二):MapReduce程序(Java)
Java版本程序开发过程主要包含三个步骤,一是map.reduce程序开发:第二是将程序编译成JAR包:第三使用Hadoop jar命令进行任务提交. 下面拿一个具体的例子进行说明,一个简单的词频统计 ...
- CRM (知识点)
插件 Django内置Admin Django Admin流程 ModelForm 自定义分页 curd 插件 权限 业务
- (五)HttpClient 连接超时及读取超时
第一节: HttpClient 连接超时及读取超时 HttpClient连接超时及读取超时 httpClient在执行具体http请求时候 有一个连接的时间和读取内容的时间: HttpClient连接 ...
- sql server 提取汉字/数字/字母的方法
sql server 提取汉字/数字/字母的方法 --提取数字 IF OBJECT_ID('DBO.GET_NUMBER2') IS NOT NULL DROP FUNCTION DBO.GET_NU ...
- 高版本SQL备份在低版本SQL还原问题
问题描述: 高版本SQL备份在低版本SQL还原问题(出现媒体簇的结构不正确) 分析原因: SQL版本兼容问题,SQL SERVER兼容级别是用作向下兼容用,高版本的SQL备份在低版本中不兼容 ...
- (转载)使用SQL-Server创建一个银行数据管理系统Ⅰ
首先,要创建一个完整的数据管理系统,不是一蹴而就的,一定要要一步一步的来,不断完善,最终方能达到自己想要的结果,所以我在这里也是一点一点分步来做的. 创建数据库,数据库属性在这里用的是默认(不推荐使用 ...