来自蒟蒻 \(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. Ionic2 播放mp3功能实现

    在开发app的过程中有需要播放mp3的功能,一直想实现,但苦于具体的困难一直未能实现,经过一段时间的资料查询和测试,最终摸索出来,现记录如下: 1.最重要的是安装第三方插件ionic-audio,开源 ...

  2. Mac 启动 ssh 服务

    Mac 本身有 ssh,只是没有默认开启,需要手动开启. 启动 sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist 关闭 su ...

  3. Spring RPC 入门学习(1)-HelloWorld入门

    Spring搭建RPC环境 第一,下载所需要的jar包,下载地址:https://yunpan.cn/cPErQeANrSMyB (提取码:63e5),见下图: 第二,新建动态WebProject,把 ...

  4. poj3126 Prime Path(c语言)

    Prime Path   Description The ministers of the cabinet were quite upset by the message from the Chief ...

  5. doc窗口 输入命令net start mysql 服务名无效

    解决方案: 1.win+R键输入cmd敲回车进入dos界面: 2.输入cd d:/mysql-5.5.25/bin敲回车,发现没变化: 3.输入d:敲回车,定位到d:\mysql-5.5.25\bin ...

  6. Linux内核分析作业 NO.7

    可执行程序的装载 于佳心  原创作品转载请注明出处  <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实 ...

  7. 《Metasploit渗透测试魔鬼训练营》第一章读书笔记

    第1章 魔鬼训练营--初识Metasploit 20135301 1.1 什么是渗透测试 1.1.1 渗透测试的起源与定义 如果大家对军事感兴趣,会知道各国军队每年都会组织一些军事演习来锻炼军队的攻防 ...

  8. Junit4使用实验报告

    一.题目简介 Junit4的使用及求和测试. 二.源码的github链接 https://github.com/bjing123/test-/blob/master/Arithmetic.txt ht ...

  9. 现代程序设计 homework-01

    搞了6个小时individual project...看看博客做一做第一次现代程序设计作业 1) 建立 GitHub 账户, 把课上做的 “最大子数组之和” 程序签入 我的github地址是https ...

  10. Alpha冲刺随笔汇总

    项目Alpha冲刺(团队) Alpha冲刺随笔汇总 姓名 学号 博客链接 何守成 031602408 http://www.cnblogs.com/heshoucheng/ 黄锦峰 031602411 ...