小细节磕磕碰碰浪费了半个多小时的时间

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]森林的更多相关文章

  1. [bzoj3123] [SDOI2013]森林 主席树+启发式合并+LCT

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  2. 【bzoj3123】[Sdoi2013]森林 倍增LCA+主席树+启发式合并

    题目描述 输入 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负 ...

  3. P3302 [SDOI2013]森林(主席树+启发式合并)

    P3302 [SDOI2013]森林 主席树+启发式合并 (我以前的主席树板子是错的.......坑了我老久TAT) 第k小问题显然是主席树. 我们对每个点维护一棵包含其子树所有节点的主席树 询问(x ...

  4. 【BZOJ-3123】森林 主席树 + 启发式合并

    3123: [Sdoi2013]森林 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2738  Solved: 806[Submit][Status] ...

  5. BZOJ_3123_[Sdoi2013]森林_主席树+启发式合并

    BZOJ_3123_[Sdoi2013]森林_主席树+启发式合并 Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20 ...

  6. Bzoj 3123: [Sdoi2013]森林(主席树+启发式合并)

    3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当前 ...

  7. Bzoj2534:后缀自动机 主席树启发式合并

    国际惯例的题面:考虑我们求解出字符串uvu第一个u的右端点为i,第二个u的右端点为j,我们需要满足什么性质?显然j>i+L,因为我们选择的串不能是空串.另外考虑i和j的最长公共前缀(也就是说其p ...

  8. 【主席树启发式合并】【P3302】[SDOI2013]森林

    Description 给定一个 \(n\) 个节点的森林,有 \(Q\) 次操作,每次要么将森林中某两点联通,保证操作后还是个森林,要么查询两点间权值第 \(k\) 小,保证两点联通.强制在线. L ...

  9. Bzoj 3673: 可持久化并查集 by zky(主席树+启发式合并)

    3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MB Description n个集合 m个操作 操作: 1 a b 合并a,b所在集 ...

随机推荐

  1. 关于Struts漏洞工具的使用

    最新struts-scan资源: https://www.cesafe.com/3486.html 一,将资源下载后,放入liunx系统中,并且需要具备python2的操作环境 二,打开终端使用如下命 ...

  2. jQuery EasyUI/TopJUI创建文本验证框(不写js,纯HTML实现!!!)

    jQuery EasyUI/TopJUI创建文本验证框(不写js,纯HTML实现!!!) validatebox(验证框)的设计目的是为了验证输入的表单字段是否有效.如果用户输入了无效的值,它将会更改 ...

  3. urlencode()和urldecode()

    urlencode()函数原理就是首先把中文字符转换为十六进制,然后在每个字符前面加一个标识符%.一般用在url链接地址编码urldecode()函数与urlencode()函数原理相反,用于解码已编 ...

  4. Codeforces Round #563 (Div. 2) B. Ehab Is an Odd Person

    链接:https://codeforces.com/contest/1174/problem/B 题意: You're given an array aa of length nn. You can ...

  5. HDU 5883 F - The Best Path 欧拉通路 & 欧拉回路

    给定一个图,要求选一个点作为起点,然后经过每条边一次,然后把访问过的点异或起来(访问一次就异或一次),然后求最大值. 首先为什么会有最大值这样的分类?就是因为你开始点选择不同,欧拉回路的结果不同,因为 ...

  6. 牛客网Java刷题知识点之什么是内部类、为什么要使用内部类、内部类如何使用外部类的属性和方法、成员内部类、局部内部类、静态内部类、匿名内部类

    不多说,直接上干货! 可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类是一个非常有用的特性但又比较难理解使用的特性(鄙人到现在都没有怎么使用过内部类,对内部类也只是略知一二). 内部类 ...

  7. 微信支付(java版本)_支付结果通知

    应用场景: 支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答. 对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新 ...

  8. MVC 路由URL重写

    在现今搜索引擎制霸天下的时代,我们不得不做一些东西来讨好爬虫,进而提示网站的排名来博得一个看得过去的流量. URL重写与优化就是搜索引擎优化的手段之一. 假如某手机网站(基于ASP.NET MVC)分 ...

  9. 13.JAVA-包package、import使用

    1.包的定义 之前我们学习java时,生成的class文件都是位于当前目录中,假如出现了同名文件,则会出现文件覆盖问题,因此就需要设置不同的目录(定义包),来解决同名文件冲突问题. 并且在大型项目中, ...

  10. JVM垃圾回收机制四

    GCRoots与可达性分析 Java中的四种引用 强引用.软引用.弱引用.虚引用.这四种引用的强度是逐渐减弱的,JVM垃圾回收的力度是逐渐增强的. 四种引用的作用 1.可以让程序员通过代码来控制对象的 ...