bzoj3514 Codechef MARCH14 GERALD07加强版 lct预处理+主席树
Codechef MARCH14 GERALD07加强版
Time Limit: 60 Sec Memory Limit: 256 MB
Submit: 1951 Solved: 746
[Submit][Status][Discuss]
Description
N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。
Input
第一行四个整数N、M、K、type,代表点数、边数、询问数以及询问是否加密。
接下来M行,代表图中的每条边。
接下来K行,每行两个整数L、R代表一组询问。对于type=0的测试点,读入的L和R即为询问的L、R;对于type=1的测试点,每组询问的L、R应为L xor lastans和R xor lastans。
Output
K行每行一个整数代表该组询问的联通块个数。
Sample Input
1 3
1 2
2 1
3 2
2 2
2 3
1 5
5 5
1 2
Sample Output
1
3
1
HINT
对于100%的数据,1≤N、M、K≤200,000。
2016.2.26提高时限至60s
Source
题解:
首先把边依次加到图中,若当前这条边与图中的边形成了环,那么把这个环中最早加进来的边弹出去
并将每条边把哪条边弹了出去记录下来:ntr[i] = j,特别地,要是没有弹出边,ntr[i] = 0;
这个显然是可以用LCT来弄的对吧。
然后对于每个询问,我们的答案就是对l~r中ntr小于l的边求和,并用n减去这个值
正确性可以YY一下:
如果一条边的ntr >= l,那么显然他可以与从l ~ r中的边形成环,那么它对答案没有贡献
反之如果一条边的ntr < l那么它与从l ~ r中的边是不能形成环的,那么他对答案的贡献为-1
对于查询从l ~ r中有多少边的ntr小于l。
函数式线段树询问即可

比如这个图,如果询问2-5那么,对于5这条边来说,是没意义的,因为5只能将
2这条边的效果去掉,因为2最早,所以不能算,
因此ans=4-3=1而不是4-4=0
函数式线段树记录什么呢,就是rt[i]表示i为右端点,
然后左端点的话就是维护前缀和的形式即可。
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstdio> #define inf 1000000000
#define ll long long
#define N 400005
#define M 200005
#define NUM 4000007
using namespace std;
inline 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;
} int n,m,q,ans,tot,sz,flag;
int s[N],st[M],root[M];
int c[N][],fa[N],val[N],mn[N],sum[NUM],ls[NUM],rs[NUM],rev[N];
struct Node
{
int u,v;
}e[M]; inline bool isroot(int x){return c[fa[x]][]!=x&&c[fa[x]][]!=x;}
void update(int p)
{
int l=c[p][],r=c[p][];mn[p]=p;
if(val[mn[l]]<val[mn[p]])mn[p]=mn[l];
if(val[mn[r]]<val[mn[p]])mn[p]=mn[r];
}
void pushdown(int x)
{
int l=c[x][],r=c[x][];
if(rev[x])
{
rev[x]^=;rev[l]^=;rev[r]^=;
swap(c[x][],c[x][]);
}
}
void rotate(int x)
{
int y=fa[x],z=fa[y],l,r;
if(c[y][]==x)l=;else l=;r=l^;
if(!isroot(y))
{
if(c[z][]==y)c[z][]=x;else c[z][]=x;
}
fa[y]=x,fa[x]=z,fa[c[x][r]]=y;
c[y][l]=c[x][r],c[x][r]=y;
update(y),update(x);
}
void splay(int x)
{
int top=;s[++top]=x;
for(int i=x;!isroot(i);i=fa[i])s[++top]=fa[i];
for(int i=top;i;i--)pushdown(s[i]);
while(!isroot(x))
{
int y=fa[x],z=fa[y];
if(!isroot(y))
{
if(c[y][]==x^c[z][]==y)rotate(x);
else rotate(y);
}
rotate(x);
}
update(x);
}
void access(int x)
{
for(int t=;x!=;t=x,x=fa[x])
splay(x),c[x][]=t,update(x);
}
void makeroot(int x)
{
access(x);
splay(x);
rev[x]^=;
}
void link(int x,int y)
{
makeroot(x);
fa[x]=y;
}
void cut(int x,int y)
{
makeroot(x),access(y),splay(y);
c[y][]=fa[x]=;
}
int find(int x)
{
access(x),splay(x);
while(c[x][])
x=c[x][];
return x;
}
int query(int x,int y)
{
makeroot(x);
access(y);
splay(y);
return mn[y];
}
void ins(int l,int r,int x,int &y,int val)
{
y=++sz,sum[y]=sum[x]+;
if(l==r)return;
ls[y]=ls[x];rs[y]=rs[x];
int mid=(l+r)>>;
if(val<=mid)ins(l,mid,ls[x],ls[y],val);
else ins(mid+,r,rs[x],rs[y],val);
}
int query(int l,int r,int x,int y,int val)
{
if(r==val)return sum[y]-sum[x];
int mid=(l+r)>>;
if(val<=mid)return query(l,mid,ls[x],ls[y],val);
else return sum[ls[y]]-sum[ls[x]]+query(mid+,r,rs[x],rs[y],val);
}
void init()
{
tot=n;
for(int i=;i<=m;i++)
{
int u=e[i].u,v=e[i].v;
if(u==v){st[i]=i;continue;}
if(find(u)==find(v))
{
int t=query(u,v),x=val[t];
st[i]=x;
cut(e[x].u,t);cut(e[x].v,t);
}
tot++,mn[tot]=tot,val[tot]=i;
link(u,tot),link(v,tot);
}
for(int i=;i<=m;i++)
ins(,m,root[i-],root[i],st[i]);
}
int main()
{
n=read(),m=read(),q=read(),flag=read();
val[]=inf;
for(int i=;i<=n;i++) mn[i]=i,val[i]=inf;
for(int i=;i<=m;i++) e[i].u=read(),e[i].v=read(); init(); for(int i=;i<=q;i++)
{
int l=read(),r=read();
if(flag)l^=ans,r^=ans;
ans=n-query(,m,root[l-],root[r],l-);
printf("%d\n",ans);
}
}
bzoj3514 Codechef MARCH14 GERALD07加强版 lct预处理+主席树的更多相关文章
- BZOJ3514: Codechef MARCH14 GERALD07加强版(LCT,主席树)
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密.接下来M ...
- [BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2177 Solved: 834 ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT维护最大生成树 主席树
题面 考虑没有询问,直接给你一个图问联通块怎么做. 并查集是吧. 现在想要动态地做,那么应该要用LCT. 考虑新加进来一条边,想要让它能够减少一个联通块的条件就是现在边的两个端点还没有联通. 如果联通 ...
- 【BZOJ3514】Codechef MARCH14 GERALD07加强版(LCT_主席树)
题目: BZOJ3514 分析: 看到这题真的是一脸懵逼无从下手,只好膜题解.看到「森林的联通块数 = 点数 - 边数」这一句话就立刻什么都会了 QAQ . 这题最重要的就是意识到上面那个式子(正确性 ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3514 题意概括 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. N ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树
自己独自想出来并切掉还是很开心的~ Code: #include <bits/stdc++.h> #define N 400005 #define inf 1000000000 #defi ...
- 【LCT+主席树】BZOJ3514 Codechef MARCH14 GERALD07加强版
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2023 Solved: 778 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1312 Solved: 501 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版( LCT + 主席树 )
从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ...
随机推荐
- Xml文档数据提取到Excel表中
近期,财务一位同事,吐槽:<某XX开票软件>导出数据文档只有Xml格式,竟然没有Excel文档,工作起来非常不方便,希望我想想办法.上图: 需求分析:Xml数据----> 提取到Da ...
- flutter基础
1.flutter安装 1.参考官网安装sdk https://flutter.io/get-started/install 安卓和IOS需要分别配置对应的开发环境,安卓建议使用as开发,安装Flut ...
- RecycleView的万能适配器
转载自http://www.cnblogs.com/liushilin/p/5720926.html 由于RecyclerView的Adapter必须继承自RecyclerView.Adapter,并 ...
- http://blog.chinaunix.net/uid-9845710-id-1996675.html snmpd配置
http://blog.chinaunix.net/uid-9845710-id-1996675.html http://lihuipeng.blog.51cto.com/3064864/643960 ...
- sql语句分为三类(DML,DDL,DCL)-介绍
本文知识来源自:<Oracle专家高级编程> 分享作者:Vashon 时间:20150415 DDL is Data Definition Language statements. Som ...
- Codeforces GYM 100741A . Queries
time limit per test 0.25 seconds memory limit per test 64 megabytes input standard input output stan ...
- System.currentTimeMillis()与日期之间的相互转换
System.currentTimeMillis()与日期 之间是可以相互转换的,大多数Android开发者都知道 通过 SimpleDateFormat dateformat = new Simpl ...
- break,continue,return的区别
break,continue,return的区别 break 当break语句用于循环语句时,会终止执行循环,并执行循环后代码(如果有的话). function main() { for(var i ...
- Python3基础教程(十六)—— 迭代器、生成器、装饰器
在这个实验里我们学习迭代器.生成器.装饰器有关知识. 这几个概念是 Python 中不容易理解透彻的概念,务必把所有的实验代码都完整的输入并理解清楚其中每一行的意思. 迭代器 Python 迭代器(I ...
- 下拉列表事件 Dropdown iview
<Dropdown @on-click="export"> <Button icon='md-log-out'> 000l <Icon type=&q ...