BZOJ 3673 可持久化并查集 by zky && 3674 可持久化并查集加强版

题目大意:维护一种数据结构实现可持久化并查集。

思路:利用可持久化线段树实现可持久化数组维护可持久化并查集。(不知道3674哪里加强了。。。

CODE:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define RANGE 8000010
#define MAX 200200
using namespace std;

struct SegTree{
    SegTree *son[2];
    int val;

    void *operator new(size_t,SegTree *_,SegTree *__,int ___);
}mempool[RANGE],*C = mempool,*father[MAX],*h[MAX];
void *SegTree:: operator new(size_t,SegTree *_,SegTree *__,int ___) {
    C->son[0] = _;
    C->son[1] = __;
    C->val = ___;
    return C++;
}

int cnt,asks;
int verson[MAX],now_ver,latest;
int last_ans;

SegTree *Modify(SegTree *a,int l,int r,int x,int val)
{
    if(l == r)  return new(NULL,NULL,val)SegTree;
    int mid = (l + r) >> 1;
    if(x <= mid) return new(Modify(a->son[0],l,mid,x,val),a->son[1],0)SegTree;
    return new(a->son[0],Modify(a->son[1],mid + 1,r,x,val),0)SegTree;
}

int Ask(SegTree *a,int l,int r,int x)
{
    if(l == r)  return a->val;
    int mid = (l + r) >> 1;
    if(x <= mid) return Ask(a->son[0],l,mid,x);
    return Ask(a->son[1],mid + 1,r,x);
}

inline int Find(int x)
{
    int y;
    while(x)
        x = Ask(father[now_ver],1,cnt,y = x);
    return y;
}

inline void Unite(int x,int y)
{
    int fx = Find(x),fy = Find(y);
    if(fx == fy)    return ;
    ++latest;
    int hx = Ask(h[now_ver],1,cnt,fx);
    int hy = Ask(h[now_ver],1,cnt,fy);
    if(hx < hy)
        swap(x,y),swap(fx,fy),swap(hx,hy);
    father[latest] = Modify(father[now_ver],1,cnt,fy,fx);
    h[latest] = Modify(h[now_ver],1,cnt,fx,hx + hy);
    now_ver = latest;
}

inline bool Query(int x,int y)
{
    return Find(x) == Find(y);
}  

int main()
{
    cin >> cnt >> asks;
    father[0] = new(C,C,0)SegTree;
    h[0] = new(C,C,1)SegTree;
    for(int flag,x,y,i = 1; i <= asks; ++i) {
        scanf("%d",&flag);
        if(flag == 1) {
            scanf("%d%d",&x,&y);
            x ^= last_ans,y ^= last_ans;
            Unite(x,y);
        }
        else if(flag == 2) {
            scanf("%d",&x);
            x ^= last_ans;
            now_ver = verson[x];
        }
        else {
            scanf("%d%d",&x,&y);
            x ^= last_ans,y ^= last_ans;
            printf("%d\n",last_ans = Query(x,y));
        }
        verson[i] = now_ver;
    }
    return 0;
}

时间: 2024-10-10 13:33:56

BZOJ 3673 可持久化并查集 by zky && 3674 可持久化并查集加强版的相关文章

【BZOJ】3673: 可持久化并查集 by zky &amp; 3674: 可持久化并查集加强版(可持久化线段树)

http://www.lydsy.com/JudgeOnline/problem.php?id=3674 http://www.lydsy.com/JudgeOnline/problem.php?id=3673 双倍经验啦啦啦.. 给主席树换了个名称果然高大上... 首先要可持久化并查集其实就是可持久化数组... 那么因为数组的形式是这样的$P[x]$,那么我们用一种数据结构实现查找x返回对应的$P[x]$即可啦啦啦. 然后那么我所学的可持久化目前只有主席树QAQ哪天去写写fhqtreap...

bzoj3673可持久化并查集 by zky&amp;&amp;bzoj3674可持久化并查集加强版

bzoj3673可持久化并查集 by zky 题意: 维护可以恢复到第k次操作后的并查集. 题解: 用可持久化线段树维护并查集的fa数组和秩(在并查集里的深度),不能路径压缩所以用按秩启发式合并,可以使合并均摊复杂度为O(nlog2n).可持久化线段树实际上就是在更新节点时按主席树的插入方式新建一条路径(其实主席树就是可持久化权值线段树). 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm&g

【BZOJ 3674】可持久化并查集加强版&amp;【BZOJ 3673】可持久化并查集 by zky 用可持久化线段树破之

最后还是去掉异或顺手A了3673,,, 并查集其实就是fa数组,我们只需要维护这个fa数组,用可持久化线段树就行啦 1:判断是否属于同一集合,我加了路径压缩. 2:直接把跟的值指向root[k]的值破之. 3:输出判断即可. 难者不会,会者不难,1h前我还在膜这道题,现在吗hhh就当支持下zky学长出的题了. 3673: #include<cstdio> #include<cstring> #include<algorithm> #define read(x) x=ge

[bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)

Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0<n,m<=2*10^4 Input Output Sample Input 5 6 1 1 2 3 1 2 2 0 3 1 2 2 1 3 1 2 Sample Output 1 0 1 Solution 用rope实现可持久化数组,用rope的历史记录功能实现可持久化并查集,通过时间168ms

BZOJ 3673: 可持久化并查集 by zky

3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 2084  Solved: 941[Submit][Status][Discuss] Description n个集合 m个操作操作:1 a b 合并a,b所在集合2 k 回到第k次操作之后的状态(查询算作操作)3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0<n,m<=2*10^4 Input Output Sample Input 5 6

BZOJ 3674 可持久化并查集加强版(主席树变形)

3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 2515  Solved: 1107 [Submit][Status][Discuss] Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0<n,m<=2*10^4 Input Output Sample Inp

BZOJ 3674: 可持久化并查集加强版

3674: 可持久化并查集加强版 Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 2605  Solved: 977[Submit][Status][Discuss] Description Description:自从zkysb出了可持久化并查集后……hzwer:乱写能AC,暴力踩标程KuribohG:我不路径压缩就过了!ndsf:暴力就可以轻松虐!zky:…… n个集合 m个操作操作:1 a b 合并a,b所在集合2 k 回到第k次操作之后的状

Solr集群的搭建以及使用(内涵zookeeper集群的搭建指南)

1   什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud.当一个系统的索引数据量少的时候是不需要使用SolrCloud的,当索引量很大,搜索请求并发很高,这时需要使 用SolrCloud来满足这些需求. SolrCloud是基于Solr和Zookeeper的分布式搜索方案,它的主要思想是使用Zookeeper作为集群的配置信息中心. 它有几个特色功能: 1)集中式的配置信息 2)自动容

通过jedis连接redis单机成功,使用redis客户端可以连接集群,但使用JedisCluster连接redis集群一直报Could not get a resource from the pool

一,问题描述: (如题目)通过jedis连接redis单机成功,使用JedisCluster连接redis集群一直报Could not get a resource from the pool 但是使用redis客户端可以连接集群(我使用的redis desktop manager) 在java中通过jedis连接redis单机也成功,但使用JedisCluster连接redis集群一直报Could not get a resource from the pool, 我以命令行方式操作是没问题的