Read problems statements in Mandarin Chineseand Russian.

Problem Statement

Chef has a undirected graph G. This graph consists of N vertices and M edges. Each vertex of the graph has an unique index from 1 to N, also each edge of the graph has an unique index from 1 to M.

Also Chef has Q pairs of integers: LiRi (1 ≤ Li ≤ Ri ≤ M). For each pair LiRi, Chef wants to know: how many connected components will contain graph G if Chef erase all the edges from the graph, except the edges with indies X, where Li ≤ X ≤ Ri. Please, help Chef with these queries.

Input

The first line of the input contains an integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains three integers NMQ. Each of the next M lines contains a pair of integers ViUi - the current edge of graph G. Each of the next Q lines contains a pair of integers LiRi - the current query.

Output

For each query of each test case print the required number of connected components.

Constraints

  • 1 ≤ T ≤ 1000.
  • 1 ≤ NMQ ≤ 200000.
  • 1 ≤ UiVi ≤ N.
  • 1 ≤ Li ≤ Ri ≤ M.
  • Sum of all values of N for test cases is not greater than 200000. Sum of all values of M for test cases is not greater than 200000. Sum of all values of Q for test cases is not greater than 200000.
  • Graph G can contain self-loops and multiple edges.

Example

Input:
2
3 5 4
1 3
1 2
2 1
3 2
2 2
2 3
1 5
5 5
1 2
1 1 1
1 1
1 1
Output:
2
1
3
1
1

破题坑了一晚上

题目大意?见上面超链接的中文题面。

树 LCT 动态维护生成树

将所有询问按右端点递增顺序排序,从1到m依次加边。

用LCT维护当前的生成树,生成树中保留的是编号尽量大的边。

同时用线段树维护生成树中保留了哪些边(权值线段树,存编号)。

查询时,在线段树上查询$[L,R]$范围内有多少条边,若查询结果为$ x $,则连通块数为$n-x$

注意有自环和重边,这使得维护生成树的时候不能一律删编号最靠前的边,而要先查询生成树中有没有重边。

细节蛮多的。

注意多组数据,初始化结点的时候要初始化到n+m

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct edge{
int x,y;
}e[mxn];
struct query{
int L,R;
int id;
bool operator < (const query &b)const{
return R<b.R;
}
}q[mxn];
int ans[mxn];
//
struct SGT{
int smm[mxn<<];
#define ls rt<<1
#define rs rt<<1|1
void clear(int ed){
ed=ed<<;
for(register int i=;i<=ed;i++)smm[i]=;
}
void pushup(int rt){smm[rt]=smm[ls]+smm[rs];return;}
void update(int p,int v,int l,int r,int rt){
if(l==r){
smm[rt]+=v;
return;
}
int mid=(l+r)>>;
if(p<=mid)update(p,v,l,mid,ls);
else update(p,v,mid+,r,rs);
pushup(rt);
return;
}
int query(int L,int R,int l,int r,int rt){
if(L<=l && r<=R){
return smm[rt];
}
int mid=(l+r)>>;
if(R<=mid)return query(L,R,l,mid,ls);
if(L>mid)return query(L,R,mid+,r,rs);
return query(L,R,l,mid,ls)+query(L,R,mid+,r,rs);
}
#undef ls
#undef rs
}SG;
int n,m,Q;
//
struct node{
int ch[],fa;
int val,mn,minpos;
bool rev;
}t[mxn];
int cnt=;
void rever(int x){
int &lc=t[x].ch[],&rc=t[x].ch[];
swap(lc,rc);
t[lc].rev^=;t[rc].rev^=;
return;
}
void PD(int x){
if(t[x].rev){
rever(x);
t[x].rev=;
}
return;
}
void pushup(int x){
int lc=t[x].ch[],rc=t[x].ch[];
t[x].mn=t[x].val;t[x].minpos=x;
if(t[lc].mn<t[x].mn){
t[x].mn=t[lc].mn; t[x].minpos=t[lc].minpos;
}
if(t[rc].mn<t[x].mn){
t[x].mn=t[rc].mn; t[x].minpos=t[rc].minpos;
}
return;
}
inline bool isroot(int x){
return (t[t[x].fa].ch[]^x)&&(t[t[x].fa].ch[]^x);
}
void rotate(int x){
int y=t[x].fa,z=t[y].fa,lc,rc;
if(t[y].ch[]==x)lc=;else lc=;rc=lc^;
if(!isroot(y)){
t[z].ch[t[z].ch[]==y]=x;
}
t[x].fa=z;t[y].fa=x;
t[t[x].ch[rc]].fa=y;
t[y].ch[lc]=t[x].ch[rc];
t[x].ch[rc]=y;
pushup(y);
return;
}
int st[mxn],top=;
void Splay(int x){
st[top=]=x;
for(int i=x;t[i].fa;i=t[i].fa){
st[++top]=t[i].fa;
}
while(top)PD(st[top--]);
while(!isroot(x)){
int y=t[x].fa,z=t[y].fa;
if(!isroot(y)){
if((t[y].ch[]==x)^(t[z].ch[]==y))rotate(x);
else rotate(y);
}
rotate(x);
}
pushup(x);
return;
}
//
void access(int x){
for(int y=;x;x=t[x].fa){
Splay(x);
t[x].ch[]=y;
pushup(x);
y=x;
}
return;
}
int find(int x){
access(x);Splay(x);
while(t[x].ch[]){
x=t[x].ch[];
}
return x;
}
void mkroot(int x){
access(x);Splay(x);
t[x].rev^=;
return;
}
void link(int x,int y){
mkroot(x); t[x].fa=y;
return;
}
void cut(int x,int y){
mkroot(x);
access(y);Splay(y);
if(t[y].ch[]==x){t[x].fa=;t[y].ch[]=;}
pushup(y);
return;
}
//
void solve(){
int hd=;
cnt=n;
for(int i=;i<=m;i++){//按序加边
int x=e[i].x,y=e[i].y;
if(x!=y && find(x)==find(y)){
bool flag=;
mkroot(x);access(y);Splay(y);
//
/* printf("-----\n");
for(int j=1;j<=cnt;j++){
printf("#%d: lc:%d rc:%d fa:%d\n",j,t[j].ch[0],t[j].ch[1],t[j].fa);
}
printf("-----\n");*/
//
int res=t[y].ch[];
while(t[res].ch[])res=t[res].ch[];
res=res-n;
if(res> && e[res].x==x && e[res].y==y){
flag=;
cut(x,res+n);
cut(y,res+n);
SG.update(res,-,,m,);
}
//
if(!flag){
mkroot(x);access(y);Splay(y);
int tar=t[y].minpos;
cut(e[tar-n].x,tar);
cut(e[tar-n].y,tar);
SG.update(tar-n,-,,m,);
}
}
++cnt;
if(x!=y){
t[cnt].val=t[cnt].mn=i;
t[cnt].minpos=cnt;
link(x,cnt);
link(cnt,y);
SG.update(i,,,m,);
}
while(hd<=Q && q[hd].R<=i){
if(q[hd].R==i){
ans[q[hd].id]=n-SG.query(q[hd].L,q[hd].R,,m,);
}
hd++;
}
}
return;
}
void init(int n,int m){
int ed=n+m;
t[].minpos=;t[].mn=INF;
for(register int x=;x<=ed;x++){
t[x].ch[]=t[x].ch[]=t[x].fa=;
t[x].minpos=;t[x].mn=INF;
t[x].val=INF;
t[x].rev=;
}
SG.clear(ed);
return;
}
int main(){
// freopen("in.txt","r",stdin);
int i;
int T=read();
while(T--){
n=read();m=read();Q=read();
init(n,m);
for(i=;i<=m;i++){
e[i].x=read();e[i].y=read();
if(e[i].x>e[i].y)swap(e[i].x,e[i].y);
}
for(i=;i<=Q;i++){
q[i].L=read();q[i].R=read();
q[i].id=i;
}
sort(q+,q+Q+);
solve();
for(i=;i<=Q;i++){
printf("%d\n",ans[i]);
}
}
return ;
}

[CodeChef - GERALD07 ] Chef and Graph Queries的更多相关文章

  1. [bzoj3514][CodeChef GERALD07] Chef ans Graph Queries [LCT+主席树]

    题面 bzoj上的强制在线版本 思路 首先可以确定,这类联通块相关的询问问题,都可以$LCT$+可持久化记录解决 用LCT维护生成树作为算法基础 具体而言,从前往后按照边的编号顺序扫一遍边 如果这条边 ...

  2. BZOJ3514 / Codechef GERALD07 Chef and Graph Queries LCT、主席树

    传送门--BZOJ 传送门--VJ 考虑使用LCT维护时间最大生成树,那么对于第\(i\)条边,其加入时可能会删去一条边.记\(pre_i\)表示删去的边的编号,如果不存在则\(pre_i = 0\) ...

  3. 【CodeChef】Chef and Graph Queries

    Portal --> CC Chef and Graph Queries Solution 快乐数据结构题(然而好像有十分优秀的莫队+可撤销并查集搞法qwq) 首先考虑一种方式来方便一点地..计 ...

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

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

  5. Chef and Graph Queries CodeChef - GERALD07

    https://vjudge.net/problem/CodeChef-GERALD07 可以用莫队+带撤销并查集做 错误记录: 1.调试时数组开小了,忘了改大就交了 2.88行和91行少了备份num ...

  6. Code Chef - Chef and Graph Queries

    传送门 题目大意 给定一个$n$个点$m$条边的无向图$(n,m\leq 200000)$. 有$q$每次询问$(q\leq 200000)$,每次给定一个区间$L,R$,求仅保留编号$\in[L,R ...

  7. [Codechef CHSTR] Chef and String - 后缀数组

    [Codechef CHSTR] Chef and String Description 每次询问 \(S\) 的子串中,选出 \(k\) 个相同子串的方案有多少种. Solution 本题要求不是很 ...

  8. Codechef FNCS Chef and Churu

    Disciption Chef has recently learnt Function and Addition. He is too exited to teach this to his fri ...

  9. 【Codechef】Chef and Bike(二维多项式插值)

    something wrong with my new blog! I can't type matrixs so I come back. qwq 题目:https://www.codechef.c ...

随机推荐

  1. lintcode-16-带重复元素的排列

    带重复元素的排列 给出一个具有重复数字的列表,找出列表所有不同的排列. #### 样例 给出列表 [1,2,2],不同的排列有: [ [1,2,2], [2,1,2], [2,2,1] ] 挑战 使用 ...

  2. .net下将exe改造为既能双击独立运行又能注册为windows服务

    最近项目中需要将一些业务的处理程序改造为windows服务,但是考虑到实际需求,也需要能够直接双击运行这些处理程序.首先第一步想到的就是原来的项目不变,只需要在加一个windows服务的项目就行.但是 ...

  3. 这些JavaScript编程黑科技,装逼指南,高逼格代码,让你惊叹不已

    Javascript是一门很吊的语言,我可能学了假的JavaScript,哈哈,大家还有什么推荐的,补充送那啥邀请码. 本文秉承着:你看不懂是你SB,我写的代码就要牛逼. 1.单行写一个评级组件 &q ...

  4. [C/C++] const用法详解

    const在C语言中算是一个比较新的描述符,我们称之为常量修饰符,意即其所修饰的对象为常量(immutable). 我们来分情况看语法上它该如何被使用. 1.函数体内修饰局部变量.例:void fun ...

  5. SQL Server的全局变量

    SQL Service中的全部变量不需要用户参与定义,在任何程序均可随时调用.并且全部变量是以@@开头 全局变量名称 描述 @@CONNECTIONS 返回 SQL Server 自上次启动以来尝试的 ...

  6. 第49天:封装自己的scrollTop

    一.scroll家族 offset 自己的偏移scroll滚动的 scrollTop和scrollLeftscrollTop 被卷去的头部当滑动滚轮浏览网页的时候,网页隐藏在屏幕上方的距离二.页面滚动 ...

  7. 网页添加提示音,用setInterval

    如果一条数据通过审核了,修改数据库中一个值,用户怎么异步动态知道自己的记录通过审核了呢,我是通过音乐和提示的方式. 网页中添加如下代码: <style> #notify { positio ...

  8. 【SQLAlchemy】SQLAlchemy修改查询字段列名

    SQLAlchemy问题记录 company price quantity Microsoft Google Google Google 要实现脚本 select price, sum(quantit ...

  9. [bzoj] 1040 骑士 || 基环外向树dp

    原题 给出n个点n条边和每个点的点权,一条边的两个断点不能同时选择,问最大可以选多少. //图是一张基环外向树森林 是不是很像舞会啊- 就是多了一条边. 所以我们考虑一下对于一棵基环外向树,拆掉一条在 ...

  10. 爆款PHP面试题

    $a = 3; $b = 6; if ($a = 4 || $b = 4) { $a++; $b++; } echo $a; //输出 1 echo $b; //输出 7 逛鸟哥博客,看评论区有个新手 ...