[BZOJ 3123]森林
这题和 COT1 一定有 JQ 喵~
线段树的启发式合并,每次要连接两个点时就对比较小的那棵树暴力 DFS 一边
然后均摊时间依旧是 logn 的,均摊真是世界上最邪恶的东西了……
然后这题的数据是要卖萌么?!
testcase 的存在意义是被阿卡林噎掉了么?!
#include <cstdio>
#include <cstring>
#include <algorithm>
const int sizeOfPoint=;
const int sizeOfEdge=;
const int sizeOfNode=; inline int lg(int);
inline void swap(int & , int & );
inline char getch();
inline int getint();
inline void putint(int); struct edge {int point; edge * next;};
edge memory_edge[sizeOfEdge], * port_edge=memory_edge;
inline edge * newedge(int, edge * );
inline void link(int, int); struct node {int c; node * l , * r; inline node();};
node * null=new node();
node memory_node[sizeOfNode], * port_node=memory_node;
inline node * newnode(node * =null);
node * insert(node * , int, int, int); int b[sizeOfPoint], s[sizeOfPoint];
int find(int);
inline void merge(int, int); int testcase;
int N, M, T, U;
int p[sizeOfPoint], q[sizeOfPoint];
int f[sizeOfPoint], d[sizeOfPoint], a[][sizeOfPoint];
edge * e[sizeOfPoint];
node * t[sizeOfPoint];
inline void clear();
inline bool cmp(int, int);
inline void discretization();
void dfs(int);
inline int lca(int, int);
inline int query(int, int, int); int main()
{
int lastans=; testcase=getint();
for (testcase=;testcase;testcase--)
{
N=getint(), M=getint(), T=getint();
clear();
for (int i=;i<=N;i++)
p[i]=getint();
for (int i=;i<=M;i++)
{
int u=getint(), v=getint();
link(u, v);
}
discretization(); for (int i=;i<=N;i++) if (f[i]==-)
{
f[i]=; d[i]=;
dfs(i);
} for (int i=;i<=T;i++)
{
char c=getch(); int x=getint()^lastans, y=getint()^lastans;
if (c=='Q')
{
int k=getint()^lastans;
lastans=query(x, y, k);
putint(lastans);
}
else
{
int bx=find(x), by=find(y);
if (bx==by) continue;
if (s[bx]<s[by]) swap(x, y);
link(x, y);
f[y]=x; d[y]=d[x]+;
dfs(y);
}
}
} return ;
} inline int lg(int x)
{
return -__builtin_clz(x);
}
inline void swap(int & x, int & y)
{
int z=x;
x=y;
y=z;
}
inline char getch()
{
register char ch;
do ch=getchar(); while (ch!='L' && ch!='Q');
return ch;
}
inline int getint()
{
register int num=;
register char ch=, last;
do last=ch, ch=getchar(); while (ch<'' || ch>'');
do num=num*+ch-'', ch=getchar(); while (ch>='' && ch<='');
if (last=='-') num=-num;
return num;
}
inline void putint(int num)
{
char stack[];
register int top=;
if (num==) stack[top=]='';
if (num<) putchar('-'), num=-num;
for ( ;num;num/=) stack[++top]=num%+'';
for ( ;top;top--) putchar(stack[top]);
putchar('\n');
} inline edge * newedge(int point, edge * next)
{
edge * ret=port_edge++;
ret->point=point; ret->next=next;
return ret;
}
inline void link(int u, int v)
{
e[u]=newedge(v, e[u]);
e[v]=newedge(u, e[v]);
merge(u, v);
} inline node::node()
{
this->c=;
this->l=this;
this->r=this;
}
inline node * newnode(node * t)
{
node * newt=port_node++;
*newt=*t;
return newt;
}
node * insert(node * t, int l, int r, int k)
{
t=newnode(t);
t->c++;
if (l==r) return t; int m=(l+r)>>;
if (k<=m) t->l=insert(t->l, l, m, k);
else t->r=insert(t->r, m+, r, k);
return t;
} int find(int u)
{
return !b[u]?u:b[u]=find(b[u]);
}
inline void merge(int u, int v)
{
u=find(u); v=find(v);
b[v]=u; s[u]+=s[v];
} inline void clear()
{
port_edge=memory_edge;
memset(e, , sizeof(e));
port_node=memory_node;
for (int i=;i<=N;i++) t[i]=null;
memset(f, -, sizeof(f));
memset(d, -, sizeof(d));
memset(b, , sizeof(b));
memset(a, , sizeof(a));
for (int i=;i<=N;i++) s[i]=;
}
inline bool cmp(int a, int b)
{
return p[a]<p[b];
}
inline void discretization()
{
static int k[sizeOfPoint]; for (int i=;i<=N;i++) k[i]=i;
std::sort(k+, k+N+, cmp); q[U=]=p[k[]]; p[k[]]=;
for (int i=;i<=N;i++)
{
if (p[k[i]]>q[U]) q[++U]=p[k[i]];
p[k[i]]=U;
}
}
void dfs(int u)
{
t[u]=insert(t[f[u]], , U, p[u]);
if (d[u]>)
{
int lim=lg(d[u]);
a[][u]=f[u];
for (int i=;i<=lim;i++)
a[i][u]=a[i-][a[i-][u]];
for (int i=lim+;i<;i++)
a[i][u]=;
} for (edge * i=e[u];i;i=i->next) if (i->point!=f[u])
{
f[i->point]=u;
d[i->point]=d[u]+;
dfs(i->point);
}
}
inline int lca(int u, int v)
{
if (d[u]<d[v]) swap(u, v);
while (int dist=d[u]-d[v]) u=a[__builtin_ctz(dist)][u];
if (u==v) return u;
for (int i=;i>=;i--)
if (a[i][u]!=a[i][v])
u=a[i][u],
v=a[i][v];
return f[u];
}
inline int query(int a, int b, int k)
{
int c=lca(a, b), d=f[c];
node * ta=t[a], * tb=t[b], * tc=t[c], * td=t[d];
int l=, r=U, m; for ( ;l<r; )
{
m=(l+r)>>;
if (ta->l->c+tb->l->c-tc->l->c-td->l->c>=k)
{
ta=ta->l; tb=tb->l; tc=tc->l; td=td->l;
r=m;
}
else
{
k-=ta->l->c+tb->l->c-tc->l->c-td->l->c;
ta=ta->r; tb=tb->r; tc=tc->r; td=td->r;
l=m+;
}
} return q[l];
}
又 R 又 T 一时爽
[BZOJ 3123]森林的更多相关文章
- BZOJ 3123 森林(函数式线段树)
		
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3123 题意: 思路:总的来说,查询区间第K小利用函数式线段树的减法操作.对于两棵树的合并 ...
 - BZOJ - 3123 森林 (可持久化线段树+启发式合并)
		
题目链接 先把初始边建成一个森林,每棵树选一个根节点递归建可持久化线段树.当添加新边的时候,把结点数少的树暴力重构,以和它连边的那个点作为父节点继承线段树,并求出倍增数组.树的结点数可以用并查集来维护 ...
 - [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)
		
[BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...
 - 【sdoi2013】森林 BZOJ 3123
		
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
 - BZOJ 3123: [Sdoi2013]森林 [主席树启发式合并]
		
3123: [Sdoi2013]森林 题意:一个森林,加边,询问路径上k小值.保证任意时刻是森林 LCT没法搞,树上kth肯定要用树上主席树 加边?启发式合并就好了,小的树dfs重建一下 注意 测试点 ...
 - bzoj 3123: [Sdoi2013]森林(45分暴力)
		
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4184 Solved: 1235[Submit][Status ...
 - AC日记——[Sdoi2013]森林 bzoj 3123
		
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 3216 Solved: 944[Submit][Status] ...
 - Bzoj 3123: [Sdoi2013]森林(主席树+启发式合并)
		
3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当前 ...
 - ●BZOJ 3123 [Sdoi2013]森林
		
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3123 题解: 主席树,在线,启发式合并 简单版(只有询问操作):[2588: Spoj 10 ...
 
随机推荐
- windows 开机启动 CassiniDev(IIS替代软件)
			
CassiniDev(IIS替代软件) 使用asp.net的时候,要部署一个iis,或者部署iis express,有时候你嫌麻烦, 这是一个替代品. 功能完全的. 下载地址:http://cassi ...
 - 实验二 简易版C语言文法
			
<程序>::=begin<语句串>end <语句串>::=<语句>{;<语句>} <语句>::=<赋值语句> < ...
 - Spring Security 从配置入门 学习讲解。刽子手------------securityConfig.xml
			
不知道我的web.xml 大家都理解了没. 废话确实有点多,可能很多知识点,大家都知道,可是我学的时候,压根什么都不懂啊.... 这篇我们要讲刽子手 securityConfig. 为什么要说他是 ...
 - json返回数据时提示字符串超出长度
			
JavaScriptSerializer json = new JavaScriptSerializer(); json.MaxJsonLength = Int32.MaxValue; return ...
 - 遗传算法的C语言实现(一):以非线性函数求极值为例
			
以前搞数学建模的时候,研究过(其实也不算是研究,只是大概了解)一些人工智能算法,比如前面已经说过的粒子群算法(PSO),还有著名的遗传算法(GA),模拟退火算法(SA),蚁群算法(ACA)等.当时懂得 ...
 - 【转】  数据库系统——B+树索引
			
原文来自于:http://blog.csdn.net/cjfeii/article/details/10858721 1. B+树索引概述 在上一篇文章中,我们讨论了关于index的几个中重要的课题: ...
 - mybatis配置log4j显示sql语句
			
log4j.properties文件下: log4j.rootLogger=DEBUG, Console #Console log4j.appender.Console=org.apache.log4 ...
 - Android编译系统参考手册
			
build/core/clear_vars.mk Clear out values of all variables used by rule templates 清除LOCAL变量,每个模块的And ...
 - 浅谈fls3的一个压缩问题
			
昨天,用fis3压缩优化,在命令行运行命令的时候,出现了一个报错信息. not a PNG file. 查了很多资料,没找到解决方案,终于在github上提问,有正主回答: 是由于有些图片的后缀是通过 ...
 - CSS和CSS选择器
			
一:CSS CSS有三种书写形式(优先级从高到低) 1)行内样式:(内联样式)直接在标签style属性中书写 2)内页样式:在本网页的style标签中书写 3)外部样式:在单独的CSS文件中书写,然后 ...