[CodeChef - GERALD07 ] Chef and Graph Queries
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: Li, Ri (1 ≤ Li ≤ Ri ≤ M). For each pair Li, Ri, 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 N, M, Q. Each of the next M lines contains a pair of integers Vi, Ui - the current edge of graph G. Each of the next Q lines contains a pair of integers Li, Ri - the current query.
Output
For each query of each test case print the required number of connected components.
Constraints
- 1 ≤ T ≤ 1000.
- 1 ≤ N, M, Q ≤ 200000.
- 1 ≤ Ui, Vi ≤ 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的更多相关文章
- [bzoj3514][CodeChef GERALD07] Chef ans Graph Queries [LCT+主席树]
题面 bzoj上的强制在线版本 思路 首先可以确定,这类联通块相关的询问问题,都可以$LCT$+可持久化记录解决 用LCT维护生成树作为算法基础 具体而言,从前往后按照边的编号顺序扫一遍边 如果这条边 ...
- BZOJ3514 / Codechef GERALD07 Chef and Graph Queries LCT、主席树
传送门--BZOJ 传送门--VJ 考虑使用LCT维护时间最大生成树,那么对于第\(i\)条边,其加入时可能会删去一条边.记\(pre_i\)表示删去的边的编号,如果不存在则\(pre_i = 0\) ...
- 【CodeChef】Chef and Graph Queries
Portal --> CC Chef and Graph Queries Solution 快乐数据结构题(然而好像有十分优秀的莫队+可撤销并查集搞法qwq) 首先考虑一种方式来方便一点地..计 ...
- [BZOJ 3514]Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES)
[BZOJ3514] Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES) 题意 \(N\) 个点 \(M\) 条边的无向图,\(K\) 次询问保 ...
- Chef and Graph Queries CodeChef - GERALD07
https://vjudge.net/problem/CodeChef-GERALD07 可以用莫队+带撤销并查集做 错误记录: 1.调试时数组开小了,忘了改大就交了 2.88行和91行少了备份num ...
- Code Chef - Chef and Graph Queries
传送门 题目大意 给定一个$n$个点$m$条边的无向图$(n,m\leq 200000)$. 有$q$每次询问$(q\leq 200000)$,每次给定一个区间$L,R$,求仅保留编号$\in[L,R ...
- [Codechef CHSTR] Chef and String - 后缀数组
[Codechef CHSTR] Chef and String Description 每次询问 \(S\) 的子串中,选出 \(k\) 个相同子串的方案有多少种. Solution 本题要求不是很 ...
- Codechef FNCS Chef and Churu
Disciption Chef has recently learnt Function and Addition. He is too exited to teach this to his fri ...
- 【Codechef】Chef and Bike(二维多项式插值)
something wrong with my new blog! I can't type matrixs so I come back. qwq 题目:https://www.codechef.c ...
随机推荐
- POSIX线程学习
一.什么是线程 在一个程序中的多个执行路线就叫做线程.更准确的定义是:线程是一个进程内部的一个控制序列.所有的进程都至少有一个线程.当进程执行fork调用时,将创建出该进程的一份新副本,这个新进程拥有 ...
- Ubuntu录制gif动态图
大神写博客的时候通常一个Demo会附带一个动态图展示效果.在windows和mac上应该很容易找到录制工具,下面记录一下我在ubuntu下录制gif的过程. 下载byzanz录制工具 在ubuntu软 ...
- 二叉树及其遍历方法---python实现
github:代码实现 本文算法均使用python3实现 1. 二叉树 1.1 二叉树的定义 二叉树是一种特殊的树,它具有以下特点: (1)树中每个节点最多只能有两棵树,即每个节点的度最多为2 ...
- 关于char, wchar_t, TCHAR, _T(),L,宏 _T、TEXT,_TEXT、L
char :单字节变量类型,最多表示256个字符, wchar_t :宽字节变量类型,用于表示Unicode字符, 它实际定义在<string.h>里:typedef unsigned s ...
- Unity3d学习日记(五)
之前用3dsmax将模型转成FBX怎么也没有办法自动导入材质到Unity3d中(试过勾选了导出嵌入媒体,没用).索性试了试c4d,发现是可行的,看来像我这种菜鸡还是更加适合用c4d. 拿zoe ...
- Java-通过比较throw与throws来阐述抛出异常
转自:http://www.cnblogs.com/Miracle-Maker/p/6239346.html 浅谈Java异常 以前虽然知道一些异常的处理,也用过一些,但是对throw和throws区 ...
- OSI参考模型和TCP/IP参考模型
- 第29天:js-数组添加删除、数组和字符串相互转换
一.添加数组var arr=[1,3,5];arr.push(7,9);//添加7和9到数组arr后面,得到[1,3,5,7,9]1.push();可向数组末尾添加一个或多个元素,并返回新的长度.2. ...
- 【刷题】BZOJ 2179 FFT快速傅立叶
Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出 ...
- BZOJ1503:[NOI2004]郁闷的出纳员——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1503 (题面复制的洛谷的,因为洛谷好看) 题目描述 OIER公司是一家大型专业化软件公司,有着数以万 ...