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. C++ Mooc学习

    # C++远征篇之起航 1.IDE搭建,现在大部分同学都使用devC,devC的debug调试功能特别好用,可以跟踪变量.省去了在中间插入一些输出语句来输出中间变量的麻烦. 2.using names ...

  2. Alpha 冲刺报告(3/10)

    Alpha 冲刺报告 队名:洛基小队 峻雄(组长) 已完成:开始编写角色的移动脚本 明日计划:继续学习并进行脚本编写 剩余任务:物品背包交互代码 困难:如何把各个模块的脚本整合起来 --------- ...

  3. iOS开发开辟线程总结--NSThread

    1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue ...

  4. QT分析之网络编程

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201002842553382/ 首先对Windows下的网络编程总结一下: 如果是服务器 ...

  5. Android基础------通知栏

    前言:Android通知栏提示笔记 通知几乎是每一款app都拥有的功能 1.发送通知 发送一个通知栏必须用到两个类:  NotificationManager . Notification. Noti ...

  6. [剑指Offer] 44.翻转单词顺序列

    题目描述 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思.例如,“student ...

  7. 前台界面(2)---CSS 样式

    目录 1. 内联样式 2. 层叠样式表CSS 2.1. 类选择器 2.1.1. 颜色设置 2.1.2. 字号设置 2.1.3. CSS边框属性 2.1.4. 设置背景颜色 2.1.5. 设置布局边框 ...

  8. 【原创】U盘插入磁盘显示脱机解决

    问题说明:插入U盘,电脑可识别硬件,打开我的电脑,无显示U盘所在的磁盘.,并且在计算机管理的磁盘管理看到的U盘为脱机状态 解决方案:1.打开命令,输入 diskpart  回车,输入list disk ...

  9. [洛谷4609] [FJOI2016]建筑师

    题目描述 LOJ题面:https://loj.ac/problem/2173. 洛谷题面:https://www.luogu.org/problemnew/show/P4609. Solution [ ...

  10. [洛谷P3950]部落冲突

    题目大意:给你一棵树,有$3$个操作: $Q\;p\;q:$询问$p,q$是否连通 $C\;p\;q:$把$p->q$这条边割断 $U\;x:$恢复第$x$次操作二 题解:可以在割断时把这条边赋 ...