题目描述:

  N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。

输入格式:

  第一行四个整数N、M、K、type,代表点数、边数、询问数以及询问是否加密。 接下来M行,代表图中的每条边。 接下来K行,每行两个整数L、R代表一组询问。对于type=0的测试点,读入的L和R即为询问的L、R;对于type=1的测试点,每组询问的L、R应为L xor lastans和R xor lastans。

输出格式:

  K行每行一个整数代表该组询问的联通块个数。

题解:

  连通问题首先考虑LCT。

  考虑连通块个数的计算方法。

  连通块个数=点数-去掉重边后的边数。

  逐个枚举边,如果这条边连接的两个点没有连通,连接这条边;反之,把两点间最早的边弹出,连接这条边,并记录弹出边的编号。

  每次查询区间时,如果这条边弹出的边在区间内,那么这条边是无效的。

  所以问题转化为求区间内小于某个数的数的个数,可以主席树维护。

  时间复杂度$O(nlog_n)$

Code:

 #include<iostream>
#include<cstdio>
using namespace std;
const int N=;
const int inf=1e9+;
int n,m,k,ty,cnt,top;
int a[N<<],st[N<<],ch[N<<][],f[N<<],rev[N<<],mi[N<<];
int u[N],v[N],rt[N],b[N],an[N];
struct seg{
int lc,rc,w;
}t[N<<];
int read()
{
int s=;char c=getchar();
while(c<''||c>'') c=getchar();
while(c>=''&&c<=''){
s=(s<<)+(s<<)+c-'';
c=getchar();
}
return s;
}
int get(int x)
{
return ch[f[x]][]==x;
}
bool isroot(int x)
{
return ch[f[x]][]!=x&&ch[f[x]][]!=x;
}
void pushup(int x)
{
mi[x]=a[x];
if(ch[x][]) mi[x]=min(mi[x],mi[ch[x][]]);
if(ch[x][]) mi[x]=min(mi[x],mi[ch[x][]]);
}
void pushdown(int x)
{
if(rev[x]){
swap(ch[x][],ch[x][]);
if(ch[x][]) rev[ch[x][]]^=;
if(ch[x][]) rev[ch[x][]]^=;
rev[x]=;
}
}
void rotate(int x)
{
int y=f[x],z=f[y],k=get(x);
if(!isroot(y)){
if(ch[z][]==y) ch[z][]=x;
else ch[z][]=x;
}
f[x]=z;f[y]=x;f[ch[x][k^]]=y;
ch[y][k]=ch[x][k^];ch[x][k^]=y;
pushup(y);pushup(x);
}
void splay(int x)
{
top=;st[++top]=x;
for(int i=x;!isroot(i);i=f[i]) st[++top]=f[i];
for(int i=top;i>=;i--) pushdown(st[i]);
while(!isroot(x)){
int y=f[x];
if(!isroot(y)){
if(get(x)==get(y)) rotate(y);
else rotate(x);
}
rotate(x);
}
}
void access(int x)
{
for(int y=;x;y=x,x=f[x]){
splay(x);ch[x][]=y;pushup(x);
}
}
void makeroot(int x)
{
access(x);splay(x);
rev[x]^=;
}
void split(int x,int y)
{
makeroot(x);
access(y);splay(y);
}
void link(int x,int y)
{
makeroot(x);
f[x]=y;
}
void cut(int x,int y)
{
split(x,y);
f[x]=ch[y][]=;
}
int find(int x)
{
access(x);splay(x);
pushdown(x);
while(ch[x][]){
pushdown(ch[x][]);
x=ch[x][];
}
splay(x);
return x;
}
void insert(int lk,int &rk,int l,int r,int x)
{
if(rk==) rk=++cnt;
t[rk].w=t[lk].w+;
if(l==r) return;
int mid=(l+r)>>;
if(x<=mid){
t[rk].rc=t[lk].rc;
insert(t[lk].lc,t[rk].lc,l,mid,x);
}
else{
t[rk].lc=t[lk].lc;
insert(t[lk].rc,t[rk].rc,mid+,r,x);
}
}
int que(int lk,int rk,int L,int R,int l,int r)
{
if(L>=l&&R<=r) return t[rk].w-t[lk].w;
int mid=(L+R)>>;
if(r<=mid) return que(t[lk].lc,t[rk].lc,L,mid,l,r);
else if(l>mid) return que(t[lk].rc,t[rk].rc,mid+,R,l,r);
else return que(t[lk].lc,t[rk].lc,L,mid,l,r)+que(t[lk].rc,t[rk].rc,mid+,R,l,r);
}
int main()
{
n=read();m=read();k=read();ty=read();
for(int i=;i<=n;i++) a[i]=inf;
for(int i=;i<=m;i++){
u[i]=read();v[i]=read();a[i+n]=i;
if(u[i]!=v[i]){
int x=find(u[i]),y=find(v[i]);
if(x==y){
split(u[i],v[i]);
b[i]=mi[v[i]];
cut(u[b[i]],b[i]+n);
cut(b[i]+n,v[b[i]]);
}
link(u[i],i+n);
link(i+n,v[i]);
insert(rt[i-],rt[i],,m,b[i]);
}
else rt[i]=rt[i-];
}
for(int i=;i<=k;i++){
int l=read(),r=read();
if(ty){
l^=an[i-];r^=an[i-];
}
an[i]=n-que(rt[l-],rt[r],,m,,l-);
}
for(int i=;i<=k;i++) printf("%d\n",an[i]);
return ;
}

GERALD07加强版题解的更多相关文章

  1. 【LCT+主席树】BZOJ3514 Codechef MARCH14 GERALD07加强版

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 2023  Solved: 778 ...

  2. [BZOJ 3514]Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES)

    [BZOJ3514] Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES) 题意 \(N\) 个点 \(M\) 条边的无向图,\(K\) 次询问保 ...

  3. bzoj3514 Codechef MARCH14 GERALD07加强版 lct预处理+主席树

    Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1951  Solved: 746[Submi ...

  4. 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1288  Solved: 490 ...

  5. BZOJ 3514: Codechef MARCH14 GERALD07加强版( LCT + 主席树 )

    从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ...

  6. BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1312  Solved: 501 ...

  7. BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT

    BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. I ...

  8. [BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 2177  Solved: 834 ...

  9. BZOJ3514 GERALD07加强版

    GERALD07 Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问 ...

随机推荐

  1. linux部署jdk-tomcat

    http://blog.csdn.net/u012187452/article/details/72595040 //参考jdk下载 一.安装JDK1 下载安装包http://blog.csdn.ne ...

  2. vue-cli创建的项目中引入第三方库报错'caller', 'calle', and 'arguments' properties may not be...

    本文链接:https://blog.csdn.net/Sophie_U/article/details/76223978 问题: 在vue的main.js中引入mui.min.js时,报错. 如上,单 ...

  3. 每天一个linux命令:mv(7)

    mv mv命令可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 在跨文件系统移动文件时,mv先拷贝,再将原有文件删除, ...

  4. STM32点LED灯

    一.建立项目模板 这里的user中重复引用了system_stm32f10x.c Output中选择Create HEXFile,并且可以选择输出路径. Listing中可以选择输出路径. 然后在C/ ...

  5. SPOJ LEXSTR 并查集

    题目描述: Taplu and Abhishar loved playing scrabble. One day they thought of inventing a new game using ...

  6. Android ROM 开发技能图谱

    # Android ROM 开发技能图谱 ## 1. 操作系统 * Ubuntu(首选)* MacOSX ## 2. 编程语言 * Java * JNI(务必掌握)* C++* C ## 3. 源码 ...

  7. js上传图片到七牛云存储

    项目开发过程中遇到一个需求,运营人员需要上传图片到七牛云,最开始的做法是,后台对接七牛,然后出一个接口,前端调用接口,先将图片传到后台,然后后台再上传七牛云,用的过程中发现,图片小的情况下还好,图片一 ...

  8. Eclipse Missing artifact jdk.tools:jdk.tools:jar:1.6

    Missing artifact jdk.tools:jdk.tools:jar:1.6 问题出在Eclipse Maven的支持上,在Eclipse下,java.home变量设置为用于启动Eclip ...

  9. 泛微oa系统com.eweaver.base.DataAction文件sql参数sql注入

    URL/ServiceAction/com.eweaver.base.DataAction?sql=select%201,2,3,4,5,6,7,8,9,233%20from%20DUAL%20

  10. java部署:CentOS 7下Tomcat安装与配置教程(Tomcat开机启动)

    一.前言 1.本教程主要内容 Tomcat安装与基础配置 Tomcat开机启动配置 2.本教程适用范围与环境信息 适用范围 软件/工具 版本说明 CentOS CentOS 7 Tomcat Tomc ...