题目描述

PDF

输入输出格式

输入格式:

输出格式:

输入输出样例

输入样例#1:

5 7
1 1 2
2 3 4
1 3 5
3 4
2 4 1
3 4
3 3
输出样例#1:

3 12
3 7
2 8

Solution:

  本题平衡树。

  考试的时候想到的就是无旋treap了,正解貌似是并查集(我没想出来,太菜了)。

  节点维护子树大小和子树和,开始时每个节点就是一棵treap,因为我们并不要保证有序,所以可以直接按中序遍历维护,合并分离就不需要考虑优先级了。

  对于操作一,若不在同一棵树中,直接merge两棵树。

  对于操作二,因为随机键值树高为$\log n$,所以直接暴力往上跳到$x$所在树的根,跳的同时求出$x$在该树中的排名,若$x,y$不在同一棵树中,按排名将$x$分离出来,与$y$所在树合并。

  对于操作三,直接找到$x$所在树根输出子树大小和子树和就好了。

代码:

/*Code by 520 -- 10.24*/
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=;
int n,m,ch[N][],rnd[N],siz[N],date[N],cnt,fa[N],sum[N]; int gi(){
int a=;char x=getchar();
while(x<''||x>'') x=getchar();
while(x>=''&&x<='') a=(a<<)+(a<<)+(x^),x=getchar();
return a;
} il void newnode(int v){
++cnt;
ch[cnt][]=ch[cnt][]=,sum[cnt]=v;
siz[cnt]=,date[cnt]=v,rnd[cnt]=rand(),fa[cnt]=;
} il void up(int rt){
if(ch[rt][]) fa[ch[rt][]]=rt;
if(ch[rt][]) fa[ch[rt][]]=rt;
siz[rt]=siz[ch[rt][]]+siz[ch[rt][]]+;
sum[rt]=sum[ch[rt][]]+sum[ch[rt][]]+date[rt];
} int merge(int x,int y){
if(!x||!y) return x+y;
if(rnd[x]<rnd[y]) {ch[x][]=merge(ch[x][],y),up(x);return x;}
else {ch[y][]=merge(x,ch[y][]),up(y);return y;}
} void split(int rt,int v,int &x,int &y){
if(!rt) {x=y=;return;}
if(siz[ch[rt][]]>=v) y=rt,split(ch[rt][],v,x,ch[y][]),up(y);
else x=rt,split(ch[rt][],v-siz[ch[rt][]]-,ch[x][],y),up(x);
} int find(int x,int &tot){
if(!fa[x])return x;
if(ch[fa[x]][]==x) tot+=siz[ch[fa[x]][]]+;
return find(fa[x],tot);
} int main(){
srand(time());
while(scanf("%d%d",&n,&m)!=EOF){
cnt=; int opt,a,b,c,x,y,z;
For(i,,n) newnode(i);
while(m--){
opt=gi(),a=gi();
if(opt==){
b=gi();
a=find(a,x=),b=find(b,x=);
if(a!=b) merge(a,b);
}
else if(opt==){ int k=siz[ch[a][]]+;
b=gi();c=find(a,k),b=find(b,opt);
if(c!=b){
x=y=z=;
split(c,k,x,y),split(x,k-,x,z),x=merge(x,y),b=merge(b,z);
fa[x]=,fa[b]=;
}
}
else {
a=find(a,x=);
printf("%d %d\n",siz[a],sum[a]);
}
}
}
return ;
}
 
 
 
 
 
 

UVA11987 Almost Union-Find的更多相关文章

  1. SQL Server-聚焦UNIOL ALL/UNION查询(二十三)

    前言 本节我们来看看有关查询中UNION和UNION ALL的问题,简短的内容,深入的理解,Always to review the basics. 初探UNION和UNION ALL 首先我们过一遍 ...

  2. SQL 提示介绍 hash/merge/concat union

    查询提示一直是个很有争议的东西,因为他影响了sql server 自己选择执行计划.很多人在问是否应该使用查询提示的时候一般会被告知慎用或不要使用...但是个人认为善用提示在不修改语句的条件下,是常用 ...

  3. LINQ to SQL语句(8)之Concat/Union/Intersect/Except

    适用场景:对两个集合的处理,例如追加.合并.取相同项.相交项等等. Concat(连接) 说明:连接不同的集合,不会自动过滤相同项:延迟. 1.简单形式: var q = ( from c in db ...

  4. SQLServer-----Union,Union All的使用方法

    转载: http://blog.csdn.net/kiqinie/article/details/8132485 select a.Name from Material as a union sele ...

  5. 假如 UNION ALL 里面的子句 有 JOIN ,那个执行更快呢

    比如: select id, name from table1 where name = 'x' union all select id, name from table2 where name =  ...

  6. sql union和union all的用法及效率

    UNION指令的目的是将两个SQL语句的结果合并起来.从这个角度来看, 我们会产生这样的感觉,UNION跟JOIN似乎有些许类似,因为这两个指令都可以由多个表格中撷取资料. UNION的一个限制是两个 ...

  7. 【oracle】union、union all、intersect、minus 的用法及区别

    一.union与union all 首先建两个view create or replace view test_view_1 as as c from dual union as c from dua ...

  8. sql with as union all

    WITH RPL (FId,Fname,Forder) AS ( SELECT ment.deptno,ment.deptname,ment.orderno FROM JTERP..fg_depart ...

  9. Oracle 中 union 和union all 的简单使用说明

    1.刚刚工作不久,经常接触oracle,但是对oracle很多东西都不是很熟.今天我们来了解一下union和union all的简单使用说明.Union(union all): 指令的目的是将两个 S ...

  10. LINQ系列:LINQ to SQL Concat/Union

    1. Concat 单列Concat var expr = (from p in context.Products select p.ProductName) .Concat( from c in c ...

随机推荐

  1. Lua 中的条件表达式

    下面这代码段看上去很熟悉,就是C#里面的条件表达式,很多其它语言也都有这么一个条件表达式. ; ; string c = "c"; string d = "d" ...

  2. Yarn 入门

    Yarn 是快速.可靠.安全的 js 包管理器. 关键词: nodejs, 包管理, yarn 简介 Yarn 是快速.可靠.安全的 js 包管理器. 快速 - Yarn 会缓存它下载的每个包,所以无 ...

  3. 4.3《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)—链接到目录

    在4.2章中我们已经会用cd进入到指定的目录中.这是导航最常见的用途之一,但是它还有几个值得关注的用途.第一个是使用cd ..(读作'see-dee 点点')返回当前目录级别的上一级: $ pwd / ...

  4. 任务(task)

    任务概述 线程(Thread)是创建并发的底层工具,因此有一定的局限性(不易得到返回值(必须通过创建共享域):异常的捕获和处理也麻烦:同时线程执行完毕后无法再次开启该线程),这些局限性会降低性能同时影 ...

  5. SpringBoot笔记

    官网: http://springboot.fun/ 收集到一个比较全的: https://blog.csdn.net/xiaoyu411502/article/details/52474037 Id ...

  6. LB层到Real Server之间访问请求的响应时间及HTTP状态码监控及报警设置

    为了监控到各业务的访问质量,基于LB层的Nginx日志,实现LB层到Real Server之间访问请求的响应时间(即upstream_response_time)及HTTP状态码(即upstream_ ...

  7. 复审Partner

    复审代码后,发现了一些问题: 首先说优点:代码十分工整,很清晰,各种类易于理解,逻辑上很通顺. 基本实现了代码功能,输出正确. 发现的缺点:对于文件后缀的识别有点问题,不能识别所需求的所有文件,只有一 ...

  8. Linux内核分析第三章读书笔记

    第三章 进程管理 3.1 进程 进程就是处于执行期的程序 进程就是正在执行的程序代码的实时结果 线程:在进程中活动的对象.每个线程都拥有一个独立的程序计数器.进程栈和一组进程寄存器. 内核调度的对象是 ...

  9. githup地址

    githup地址:https://github.com/caowenjing/test.git

  10. C学习随笔

    1)要经常复习,一些基础的知识点,学过的.讲过的实例,应多看一下,学习并掌握编程的语法.思路.实验中可看出,不少同学对以前知识没有掌握,对讲过的实例没有理解2)要经常实践,纸上得来终觉浅,绝知此事要躬 ...