【bzoj3514】 Codechef MARCH14 GERALD07加强版

http://www.lydsy.com/JudgeOnline/problem.php?id=3514 (题目链接)

题意

  给出$n$个点$m$条边的无向图,询问保留图中编号在$[l,r]$的边的时候图中的连通块的个数。

Solution

  将边的编号作为权值用LCT维护一个最大生成树,同时记录一下加入当前边$i$会把哪一条原本在生成树中的边踢掉,记作$ntr[i]$。如果不会踢掉任意一条边,那么$ntr[i]=0$。如果$i$是自环,那么$ntr[i]=i$。

  求出$ntr$数组有什么用呢,我们以它构建一棵主席树。对于一个询问$[l,r]$,我们想知道在这些边中有用的边有几条,那么有用的边$ntr$的前一条边的编号一定是在$l$之前的,所以我们在主席树上查询一下区间$[l,r]$中$ntr$在$[0,l-1]$中的边有几条。这样查出来的值就是有用的边的条数,每加入一条有用的边,都会时连通块个数-1,于是我们就可以统计答案了。

细节

  cut的时候cut的是被ntr的边两端的节点,手一快就打错了,还查了好久T_T

代码

// bzoj3514
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define lim 1000000000
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
using namespace std;const int maxn=200010;
int n,m,Q,T,ans,rt[maxn],ntr[maxn];
struct edge {int u,v;}e[maxn];
struct node {int son[2],s,rev;int& operator [] (int x) {return son[x];}
};namespace LCT {int fa[maxn<<1];node tr[maxn<<1];void reverse(int x) {tr[x].rev^=1;swap(tr[x][0],tr[x][1]);}void pushup(int x) {tr[x].s=x<=n ? inf : x;int l=tr[x][0],r=tr[x][1];if (l) tr[x].s=min(tr[x].s,tr[l].s);if (r) tr[x].s=min(tr[x].s,tr[r].s);}void pushdown(int x) {if (tr[fa[x]][0]==x || tr[fa[x]][1]==x) pushdown(fa[x]);if (tr[x].rev) {if (tr[x][0]) reverse(tr[x][0]);if (tr[x][1]) reverse(tr[x][1]);tr[x].rev^=1;}}void rotate(int x) {int y=fa[x],z=fa[y],l,r;l=tr[y][1]==x;r=l^1;if (tr[z][0]==y || tr[z][1]==y) tr[z][tr[z][1]==y]=x;fa[x]=z;fa[y]=x;fa[tr[x][r]]=y;tr[y][l]=tr[x][r];tr[x][r]=y;pushup(y);pushup(x);}void splay(int x) {pushdown(x);while (tr[fa[x]][0]==x || tr[fa[x]][1]==x) {int y=fa[x],z=fa[y];if (tr[z][0]==y || tr[z][1]==y) {if (tr[z][0]==y ^ tr[y][0]==x) rotate(x);else rotate(y);}rotate(x);}}void access(int x) {for (int y=0;x;y=x,x=fa[x])splay(x),tr[x][1]=y,pushup(x);}void makeroot(int x) {access(x);splay(x);reverse(x);}int query(int x,int y) {makeroot(x);access(y);splay(y);return tr[y].s;}void link(int x,int y) {makeroot(x);fa[x]=y;}void cut(int x,int y) {makeroot(x);access(y);splay(y);fa[x]=tr[y][0]=0;pushup(y);}int find(int x) {return fa[x] ? find(fa[x]) : x;}void main() {for (int i=1;i<=m;i++) {scanf("%d%d",&e[i].u,&e[i].v);if (e[i].u==e[i].v) ntr[i]=i;else if (find(e[i].u)==find(e[i].v)) {int x=query(e[i].u,e[i].v);ntr[i]=x-n;cut(x,e[x-n].u);cut(x,e[x-n].v);link(i+n,e[i].u);link(i+n,e[i].v);}else ntr[i]=0,link(i+n,e[i].u),link(i+n,e[i].v);}}
}namespace Chairtree {int sz;node tr[maxn*40];void build(int &u,int v,int l,int r,int val) {if (!u) u=++sz;if (l==r) {tr[u].s=tr[v].s+1;return;}int mid=(l+r)>>1;if (val<=mid) build(tr[u][0],tr[v][0],l,mid,val),tr[u][1]=tr[v][1];else build(tr[u][1],tr[v][1],mid+1,r,val),tr[u][0]=tr[v][0];tr[u].s=tr[tr[u][0]].s+tr[tr[u][1]].s;}int query(int u,int v,int l,int r,int ql,int qr) {if (!u && !v) return 0;if (l==ql && r==qr) return tr[v].s-tr[u].s;int mid=(l+r)>>1;if (qr<=mid) return query(tr[u][0],tr[v][0],l,mid,ql,qr);else if (ql>mid) return query(tr[u][1],tr[v][1],mid+1,r,ql,qr);else return query(tr[u][0],tr[v][0],l,mid,ql,mid)+query(tr[u][1],tr[v][1],mid+1,r,mid+1,qr);}
}
using namespace Chairtree;int main() {scanf("%d%d%d%d",&n,&m,&Q,&T);LCT::main();for (int i=1;i<=m;i++) build(rt[i],rt[i-1],0,m,ntr[i]);for (int l,r,i=1;i<=Q;i++) {scanf("%d%d",&l,&r);if (T) l^=ans,r^=ans;ans=n-query(rt[l-1],rt[r],0,m,0,l-1);printf("%d\n",ans);}return 0;
}

 

转载于:https://www.cnblogs.com/MashiroSky/p/6484381.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/429585.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言中将浮点数四舍五入取整的宏定义(支持正数和负数的圆整)

在实际工程项目中经常会需要将浮点型的计算结果四舍五入为整型&#xff0c;因此定义如下宏定义对浮点型进行圆整。若所需圆整的浮点型结果正负号无法确定&#xff0c;则需要将结果圆整为带符号的整型结果如int8_t、int16_t、int32_t等。对于结果>0的浮点数和<0的浮点数圆…

原码、反码、补码,计算机中所有的数都是以补码的形式存储的

计算机中所有的数都是以补码的形式存储的 原码&#xff1a; 一个数的原码就是其10进制的数转换为2进制数&#xff0c;正数的原码符号位为0&#xff0c;负数的原码符号位为1。 如10进制的数26667&#xff0c;将其转换为2进制为0110 1000 0010 1011。10进制的数-26667&#xf…

RT-Thread设备框架学习感悟

前面几周跟着野火的教程从0到1实现了RT-Thread的内核&#xff0c;对RT-Thread的调度机制和线程、定时器的底层实现有了总体的了解。后面还需进一步对齐实现细节进行探索&#xff0c;但大致先了解其框架&#xff0c;后面再进行细致的了解。在学习新知识时&#xff0c;最重要的是…

Tensorflow之RNN,LSTM

Tensorflow之RNN,LSTM #!/usr/bin/env python2 # -*- coding: utf-8 -*- """ tensorflow之RNN 循环神经网络做手写数据集分类 """import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data#设置随机数来比较两种计算…

python selenium T3

python selenium T3 既然要做自动,就得对得起自动化的这个名字。这一章我们将进一步的增加自动化测试的实用,增加自动发邮件功能、多线程 和定时任务,让我们的自动化工作真正变得高效而又强大起来。 EG1 : with open(report.html , r) as f:msg MIMEText(f.read() , _subtypeh…

RT-Thread中自定义MSH命令传入的参数是字符串,需用户自行检查和解析

如下是在将安富莱的dac8563模块对接到潘多拉开发板RT-Thread SPI设备框架中时导出到RT-Thread的自定义MSH命令&#xff0c;需要注意的是MSH传入的是字符串&#xff0c;需要自行对字符串进行解析处理。 #include "stdlib.h" /* 使用其中的函数&#xff1a;atoi(); */…

水平+垂直布局-css (借鉴)

1. 水平居中 方法一&#xff1a;margin:0 auto; &#xff08;最常用的居中布局方式&#xff09;方法二&#xff1a;text-align和inline-block的结合&#xff08;设置父元素的text-align为center&#xff09;。 这种方式最好应用于图片、按钮、文字之类的居中模式&#xff0c;否…

安富莱DAC8653模块

产品规格&#xff1a;1、供电电压 &#xff1a; 2.7 - 5.5V 【3.3V供电时&#xff0c;输出电压也可以到正负10V】2、通道数&#xff1a; 2路 &#xff08;通过1片DAC8563实现&#xff09;3、输出电压范围 &#xff1a; -10V ~ 10V 【客户可以自己更改为 0-10V输出范围。使…

AD16 SCH原理图打开正常,PCB图纸打开为空白或仍是上一个界面的解决方法

重新安装AD16并激活后&#xff0c;发现SCH图纸打开正常&#xff0c;但打开PCB图纸时要么显示一片空白&#xff0c;要么显示的还是上一屏的内容&#xff0c;重启AD16软件或者重启电脑都没有用。 【问题原因】电脑显卡驱动有问题 【解决方法】更新或重新安装电脑显卡驱动 step…

flex布局应用与踩坑

一、预告本文不是一篇入门的文章所有请符合以下条件的战斗人员绕道&#xff1a; 1、初学前端&#xff0c;对前端的传统布局还不是很熟悉的人 2、后端人员对前端不打算深入学习的同学 二、开篇flex布局原本是好几个月前就一直想学习的东西&#xff0c;当时flex布局还算是比较新鲜…

RT-Thread I/O设备模型

I/O设备指的是嵌入式系统中的一些Input输入/Output输出设备&#xff0c;输入输出设备是嵌入式系统重要的组成部分。输入和输出设备可以看做是计算机系统和外界进行沟通的桥梁&#xff0c;因此在计算机组成原理中输入输出设备是重要的组成部分。 计算机组成原理中的5大组成部分…

如何使用易我数据恢复向导恢复数码相机删除的图片

1 使用"易我数据恢复向导"的高级恢复(务必将数码相机的存储卡取出单独插入SD卡槽,而不是直接用数据线连接到电脑上,这样存储卡才能以磁盘方式显示) 2 选中对应磁盘,点击下一步 3 如果出现"分区参数不正确"提示&#xff0c;直接取消即可开始搜索 4 搜索完…

RT-Thread对GPIO操作两种方式的区别:1)通过设备操作接口2)直接通过通用GPIO设备驱动

在学习RT-Thread设备驱动框架时&#xff0c;看到潘多拉开发板的RT-Thread例程资料中的文档《AN0002-RT-Thread-通用 GPIO 设备应用笔记》有如下描述&#xff0c;因此产生使用文档中未使用的方式1&#xff09;通过设备操作接口 方法实现GPIO操作的想法&#xff01; 使用潘多拉开…

英语----情态动词(下)

should 应该 竟然 Youd should go to school right now. I should help him. How should i know. Im surprised tha he that he should be so rude to you. it worries me its a pity. You cant imagine.... ought to // 用在比较严肃的场合 You ought to take car…

清华大学-曾鸣-《ARM微控制器与嵌入式系统》I2C总线(一)

I2C是一种双向2线制同步串行通讯接口&#xff0c;是一类非常经典的串行总线通讯&#xff0c;理解好I2C通讯会帮助理解USB通讯、以太网通讯中的握手、数据帧等环节。 I2C的发展历史&#xff1a; SPI串行通讯主要是由MOTOROLA公司提出的&#xff0c;MOTOROLA公司的半导体部门独立…

清华大学-曾鸣-《ARM微控制器与嵌入式系统》I2C总线(二)

I2C&#xff08;Inter IC Bus&#xff09;的通讯数据帧&#xff1a; SCL线无方向区分&#xff0c;SDA线上有数据的流动方向。上图中灰色的代表的是主机向从机发送数据&#xff0c;此时SDA线的电平控制权由主机掌控&#xff0c;从机只能监听该线上的电平状态。白色代表的是从机向…

window.open 和showModalDialog的返回值

方法&#xff1a; 1: 在父级页面 test.aspx 的点击<input type"button" id"btnShow" οnclick"showItem();" value"显示子窗体"/>按钮触发 &#xff0c;然后 &#xff1a; <script language"JavaScript" type&qu…

RT-Thread I2C设备驱动框架的对接使用

I2C和SPI是MCU和板载芯片之间最常用的通讯方式&#xff0c;现在先介绍下I2C总线。I2C的基本原理也很简单&#xff0c;只需要两根线&#xff08;时钟线SCL和信号线SDA&#xff09;即可实现挂载在I2C总线上设备之间的相互通讯。I2C协议并未规定I2C总线上哪个是主机&#xff1f;哪…

给lnmp一键包中的nginx安装openresty的lua扩展

lnmp一键包&#xff08;https://lnmp.org&#xff09;本人在使用之后发现确实好用&#xff0c;能帮助我们快速搭建起lnmp、lamp和lnmpa的web生产环境&#xff0c;因此推荐大家可以多试试。但有的朋友可能需要使用openresty的lua扩展&#xff0c;这篇文章就会教你们怎么在军哥的…

RT-Thread 简介及架构

RT-Thread&#xff0c;全称是 Real Time-Thread&#xff0c;顾名思义&#xff0c;它是一个嵌入式实时多线程操作系统&#xff0c;基本属性之一是支持多任务&#xff0c;允许多个任务同时运行并不意味着处理器在同一时刻真地执行了多个任务。事实上&#xff0c;一个处理器核心在…