来自蒟蒻 \(Hero \_of \_Someone\) 的 \(LCT\) 学习笔记
$
$
又是一道骚题......
先讲一个结论:
假设我们用 \(LCT\) 来做这道题, 在插入边 \(i\) 的时候如果遇到了环, 则将环上最早加入的那条边删掉, 并插入边 \(i\),
记 \(cnm [i]\) 为被删除边的编号, 如果插入边 \(i\) 时没有遇到环, 则记 \(cnm[i]=0\).
那么, 每一个询问的答案即为, \(n\ -\ [l,r]中小于\ l\ 的\ cnm[i]\ 的个数\).
$
$
证明:
假设加入边 \(i\) 后形成的的环上没有 \(i\) 和 \(cnm[i]\) 这两条边, 那么这个环将变成两个连通块,
而在加入 \(i\) 且 \(cnm[i]<l\) (即在该询问中, \(cnm[i]\) 并不存在于图中)时, 这两个连通块变成了一个连通块, 即连通块数量 \(-1\) ,
所以 \([l,r]\) 中小于 \(l\) 的 \(cnm[i]\) 的个数即为减少的连通块数量, 得证.
$
$
所以这道题的做法就出来了, 用 \(LCT\) 来求 \(cnm[]\) , 主席树或者树套树维护 \([l,r]\) 中小于 \(l\) 的 \(cnm[i]\) 的个数
$
$

//made by Hero_of_Someone
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define N (400010)
#define RG register
using namespace std;
inline int gi(){ RG int x=0,q=1; RG char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
  if(ch=='-') q=-1,ch=getchar(); while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=getchar(); return q*x; }
void File(){freopen(".in","r",stdin);freopen(".out","w",stdout);}

int n,m,k,type,cnm[N];
struct Edge{int u,v;}E[N],e[N];
//------------ lct -----------------------------
int ch[N][2],fa[N],rev[N];
int val[N],Min[N];

inline void cur(int x,int y){ val[x]=Min[x]=y; }

inline void up(int x){
  Min[x]=min(Min[ch[x][0]],Min[ch[x][1]]);
  Min[x]=min(Min[x],val[x]);
}

inline void reverse(int x){
  if(!x) return ;
  swap(ch[x][0],ch[x][1]);
  rev[x]^=1;
}

inline void down(int x){
  if(!rev[x]) return ;
  reverse(ch[x][0]);
  reverse(ch[x][1]);
  rev[x]=0;
}

inline bool is_root(int x){ return ch[fa[x]][0]!=x && x!=ch[fa[x]][1]; }

inline bool lr(int x){ return x==ch[fa[x]][1]; }

inline void rotate(int x){
  RG int y=fa[x],z=fa[y],k=lr(x);
  if(!is_root(y)) ch[z][lr(y)]=x;
  fa[x]=z; fa[ch[x][k^1]]=y; fa[y]=x;
  ch[y][k]=ch[x][k^1]; ch[x][k^1]=y;
  up(y); up(x);
}

int st[N];
inline void splay(int x){
  RG int y=x,top=0;
  while(1){
    st[++top]=y;
    if(is_root(y)) break;
    y=fa[y];
  }
  for(RG int i=top;i;i--) down(st[i]);
  while(!is_root(x)){
    if(!is_root(fa[x])) rotate(lr(x)^lr(fa[x])?x:fa[x]);
    rotate(x);
  }
}

inline void access(int x){
  RG int y=0;
  while(x){ splay(x);
    ch[x][1]=y; fa[y]=x;
    up(x); y=x; x=fa[x];
  }
}

inline void make_root(int x){
  access(x); splay(x); reverse(x);
}

inline int query(int x,int y){
  make_root(x); access(y); splay(y);
  return Min[y];
}

inline int find(int x){
  while(fa[x]) x=fa[x];
  return x;
}

inline void link(int x,int y){
  if(find(x)==find(y)) return ;
  make_root(x); fa[x]=y;
}

inline void cut(int x,int y){
  make_root(x); access(y); splay(y);
  if(ch[y][0]==x) y=0,fa[x]=0,up(y);
}

inline void Insert(int id){
  RG int x=e[id].u,y=e[id].v;
  if(x==y){ cnm[id]=m+1; return ; }
  if(find(x)==find(y)){
    RG int tmp=query(x,y);
    cnm[id]=tmp;
    cut(e[tmp].u,n+tmp);
    cut(e[tmp].v,n+tmp);
  }
  cur(n+id,id);
  link(x,n+id);
  link(y,n+id);
}

inline void init(){
  n=gi(),m=gi(),k=gi(),type=gi();
  for(RG int i=0;i<=n;i++) cur(i,m+1);
  for(RG int i=1;i<=m;i++){
    e[i].u=gi(),e[i].v=gi();
    Insert(i);
  }
}

//------------ 主席树 --------------------------

int ans,cnt,A[N];
int sz,rt[N],sum[N*20];
int ls[N*20],rs[N*20];
inline void build(int& x,int y,int l,int r,int v){
  x=++sz;
  if(l==r){ sum[x]=sum[y]+1; return ; }
  RG int mid=(l+r)>>1;
  if(v<=A[mid]){ rs[x]=rs[y];
    build(ls[x],ls[y],l,mid,v);
  }
  else{ ls[x]=ls[y];
    build(rs[x],rs[y],mid+1,r,v);
  }
  sum[x]=sum[ls[x]]+sum[rs[x]];
}

inline int query(int x,int y,int l,int r,int v){
  if(l==r){ return A[l]<=v?sum[x]-sum[y]:0; }
  RG int mid=(l+r)>>1,ret=sum[ls[x]]-sum[ls[y]];
  if(v<=A[mid]) return query(ls[x],ls[y],l,mid,v);
  else return query(rs[x],rs[y],mid+1,r,v)+ret;
}

//----------------------------------------------

inline void work(){
  for(RG int i=1;i<=m;i++) A[i]=cnm[i];
  sort(A+1,A+m+1); A[0]=-1;
  for(RG int i=1;i<=m;i++)
    if(A[i]!=A[cnt]) A[++cnt]=A[i];
  if(A[cnt]<m+1) A[++cnt]=m+1;
  for(RG int i=1;i<=m;i++)
    build(rt[i],rt[i-1],1,cnt,cnm[i]);
  while(k--){
    RG int l=gi(),r=gi();
    if(type) l^=ans,r^=ans;
    ans=n-query(rt[r],rt[l-1],1,cnt,l-1);
    printf("%d\n",ans);
  }
}

int main(){ init(); work(); return 0; }

沉迷Link-Cut tree无法自拔之:[BZOJ3514] Codechef MARCH14 GERALD07 加强版的更多相关文章

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

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

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

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

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

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

  4. BZOJ3514 : Codechef MARCH14 GERALD07加强版

    以边编号为权值 用Link-cut Tree维护最大生成树 对于新加的第i条边(u,v) a[i]表示当a[i]这条边加入后连通块个数会减少 若u==v则a[i]=m 若u与v不连通则连上,a[i]= ...

  5. BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3514 题意概括 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. N ...

  6. BZOJ3514: Codechef MARCH14 GERALD07加强版【LCT】【主席树】【思维】

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

  7. BZOJ3514: Codechef MARCH14 GERALD07加强版(LCT,主席树)

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

  8. BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树

    自己独自想出来并切掉还是很开心的~ Code: #include <bits/stdc++.h> #define N 400005 #define inf 1000000000 #defi ...

  9. BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT维护最大生成树 主席树

    题面 考虑没有询问,直接给你一个图问联通块怎么做. 并查集是吧. 现在想要动态地做,那么应该要用LCT. 考虑新加进来一条边,想要让它能够减少一个联通块的条件就是现在边的两个端点还没有联通. 如果联通 ...

随机推荐

  1. java异步编程降低延迟

    目录 java异步编程降低延迟 一.ExecutorService和CompletionService 二.CompletableFuture(重要) 三.stream中的parallel(并行流) ...

  2. ionic 访问odoo11之具体业务类api接口

    在前面测试通过odoo登录的功能,这次的问题重点是如何访问后台具体的业务类的接口呢?这次就以我们在odoo中安装的lunch模块为例,目标是获取lunch.alert的数据,如下图 具体过程接上次文章 ...

  3. 通用漏洞评估方法CVSS3.0简表

    CVSS3.0计算分值共有三种维度: 1. 基础度量. 分为 可利用性 及 影响度 两个子项,是漏洞评估的静态分值. 2. 时间度量. 基础维度之上结合受时间影响的三个动态分值,进而评估该漏洞的动态分 ...

  4. ASP.NET Core使用log4net记录日志

    .NET常用的日志组件有NLog.Log4net等,.NET CORE下微软也自带了日志组件,到目前为止还没用过,而我本人常用的是log4net,下面简单讲讲.NET CORE下怎么使用log4net ...

  5. Docker 快速验证 HTML 导出 PDF 高效方案

    需求分析 项目中用到了 Echarts,想要把图文混排,当然包括 echarts 生成的 Canvas 图也导出 PDF. 设计和实现时,分析了 POI.iText.freemaker.world 的 ...

  6. 【数据库】Mysql中主键的几种表设计组合的实际应用效果

    写在前面 前前后后忙忙碌碌,度过了新工作的三个月.博客许久未新,似乎对忙碌没有一点点防备.总结下来三个月不断的磨砺自己,努力从独乐乐转变到众乐乐,体会到不一样的是,连办公室的新玩意都能引起莫名的兴趣了 ...

  7. 利用卷积神经网络(VGG19)实现火灾分类(附tensorflow代码及训练集)

    源码地址 https://github.com/stephen-v/tensorflow_vgg_classify 1. VGG介绍 1.1. VGG模型结构 1.2. VGG19架构 2. 用Ten ...

  8. KVM虚拟机管理——虚拟机克隆

    1. 概述2. 部署基本操作系统虚拟机3. 配置虚拟机3.1 修改/etc/sysconfig/network3.2 删除/etc/sysconfig/network-scripts/ifcfg-et ...

  9. C#爬虫基本知识

    url编码解码 首先引用程序集System.Web.dll 如果要解码某个url的参数值的话,可以调用下面的方法: System.Web.HttpUtility.UrlDecode(string) 对 ...

  10. 分布式监控系统Zabbix-图形集中展示插件Graphtree安装笔记

    Zabbix想要集中展示图像,唯一的选择是screen,后来zatree解决了screen的问题,但性能不够好.Graphtree 由OneOaaS开发并开源出来,用来解决Zabbix的图形展示问题, ...