3514: Codechef MARCH14 GERALD07加强版

Time Limit: 60 Sec  Memory Limit: 256 MB
Submit: 2177  Solved: 834
[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

3 5 4 0
1 3
1 2
2 1
3 2
2 2
2 3
1 5
5 5
1 2

Sample Output

2
1
3
1

HINT

对于100%的数据,1≤N、M、K≤200,000。

2016.2.26提高时限至60s

Source

用LCT求出NTR数组,然后主席树在线查询即可,比较简洁巧妙。

http://hzwer.com/4358.html

不过是两个高级数据结构合在一起,而且不是嵌套,理论上很好写。

实际上犯了很多低级错误,而且非常难调,以后一定要慢点写代码。

 #include<cstdio>
#include<algorithm>
#define lc ch[x][0]
#define rc ch[x][1]
#define rep(i,l,r) for (int i=l; i<=r; i++)
using namespace std; const int N=,K=,M=,inf=;
int n,m,Q,op,l,r,x,u,v,nd,ans,fa[N],ntr[K],root[K];
struct E{ int u,v; }e[K];
int find(int x){ return (fa[x]==x) ? x : fa[x]=find(fa[x]); } struct LCT{
int v[N],mn[N],s[N],ch[N][],f[N],tag[N];
bool isroot(int x){ return (!f[x]) || ((ch[f[x]][]!=x) && (ch[f[x]][]!=x)); }
void rev(int x){ swap(ch[x][],ch[x][]); tag[x]^=; }
void push(int x){ if (tag[x]) rev(lc),rev(rc),tag[x]=; }
void pd(int x){ if (!isroot(x)) pd(f[x]); push(x); } void upd(int x){
mn[x]=x;
if (v[mn[lc]]<v[mn[x]]) mn[x]=mn[lc];
if (v[mn[rc]]<v[mn[x]]) mn[x]=mn[rc];
} void rot(int x){
int y=f[x],z=f[y],w=ch[y][]==x;
if (!isroot(y)) ch[z][ch[z][]==y]=x;
f[x]=z; f[y]=x; f[ch[x][w^]]=y;
ch[y][w]=ch[x][w^]; ch[x][w^]=y; upd(y);
} void splay(int x){
pd(x);
while (!isroot(x)){
int y=f[x],z=f[y];
if (!isroot(y)){ if ((ch[z][]==y)^(ch[y][]==x)) rot(x); else rot(y); }
rot(x);
}
upd(x);
} void access(int x){ for (int y=; x; y=x,x=f[x]) splay(x),ch[x][]=y,upd(x); }
void mkroot(int x){ access(x); splay(x); rev(x);}
void link(int x,int y){ mkroot(x); f[x]=y; }
void cut(int x,int y){ mkroot(x); access(y); splay(y); ch[y][]=f[x]=; upd(y); }
int que(int x,int y){ mkroot(x); access(y); splay(y); return mn[y]; }
}T; struct S{
int ls[M],rs[M],sm[M]; void ins(int y,int &x,int L,int R,int pos){
x=++nd; ls[x]=ls[y]; rs[x]=rs[y]; sm[x]=sm[y]+;
if (L==R) return; int mid=(L+R)>>;
if (pos<=mid) ins(ls[y],ls[x],L,mid,pos); else ins(rs[y],rs[x],mid+,R,pos);
} int que(int x,int y,int L,int R,int k){
if (R==k){ return sm[y]-sm[x]; }
int mid=(L+R)>>;
if (k<=mid) return que(ls[x],ls[y],L,mid,k);
else return sm[ls[y]]-sm[ls[x]]+que(rs[x],rs[y],mid+,R,k);
}
}S; void Kruskal(){
int tot=n;
rep(i,,n) fa[i]=i;
rep(i,,m){
int u=e[i].u,v=e[i].v,x=find(u),y=find(v);
if (u==v) { ntr[i]=i; continue; }
if (x==y){
int t=T.que(u,v),k=T.v[t];
ntr[i]=k; T.cut(e[k].u,t); T.cut(e[k].v,t);
}else fa[x]=y;
tot++; T.mn[tot]=tot; T.v[tot]=i;
T.link(u,tot); T.link(v,tot);
}
rep(i,,m) S.ins(root[i-],root[i],,m,ntr[i]);
} void solve(){
rep(i,,Q){
scanf("%d%d",&l,&r);
if (op) l^=ans,r^=ans;
printf("%d\n",ans=n-S.que(root[l-],root[r],,m,l-));
}
} int main(){
freopen("bzoj3514.in","r",stdin);
freopen("bzoj3514.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&Q,&op);
T.v[]=inf; rep(i,,n) T.mn[i]=i,T.v[i]=inf;
rep(i,,m) scanf("%d%d",&e[i].u,&e[i].v);
Kruskal(); solve();
return ;
}

[BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)的更多相关文章

  1. BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1312  Solved: 501 ...

  2. BZOJ 3514: Codechef MARCH14 GERALD07加强版( LCT + 主席树 )

    从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ...

  3. 【BZOJ3514】Codechef MARCH14 GERALD07加强版 LCT+主席树

    题解: 还是比较简单的 首先我们的思路是 确定起点 然后之后贪心的选择边(也就是越靠前越希望选) 我们发现我们只需要将起点从后向前枚举 然后用lct维护连通性 因为强制在线,所以用主席树记录状态就可以 ...

  4. bzoj3514 Codechef MARCH14 GERALD07加强版 lct预处理+主席树

    Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1951  Solved: 746[Submi ...

  5. 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1288  Solved: 490 ...

  6. BZOJ3514: Codechef MARCH14 GERALD07加强版(LCT,主席树)

    Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密.接下来M ...

  7. BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT维护最大生成树 主席树

    题面 考虑没有询问,直接给你一个图问联通块怎么做. 并查集是吧. 现在想要动态地做,那么应该要用LCT. 考虑新加进来一条边,想要让它能够减少一个联通块的条件就是现在边的两个端点还没有联通. 如果联通 ...

  8. BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树

    自己独自想出来并切掉还是很开心的~ Code: #include <bits/stdc++.h> #define N 400005 #define inf 1000000000 #defi ...

  9. BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3514 题意概括 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. N ...

随机推荐

  1. GD库imagecopyresampled()方法详解~

    整理了一下GD库这个缩放,拉伸复制的方法 因为这个函数参数太多了~ imagecopyresampled()   /* //拷贝部分图像并调整大小 bool imagecopyresampled ( ...

  2. 【洛谷 P1502】 窗口的星星(扫描线)

    题目链接 把每个星星作为左下角,做出长为\(w-0.5\),宽为\(h-0.5\)的矩形. \(-0.5\)是因为边框上的不算. 离散化\(y\)坐标. 记录\(2n\)个\(4\)元组\((x,y1 ...

  3. HBase笔记之远程Shell界面命令行无法删除字符的解决方案

    方法一: 设置终端退格键为ASCII 127 在XShell的界面中,设置 文件 --> 属性 --> 终端 --> 键盘 --> BACKSPACE键序列,改为ASCII 1 ...

  4. Pyrhon代码的中文问题

    解决代码中出现中文乱码的问题: 使用中文需要在第一行声明编码#encoding=utf-8 或者#coding=utf-8 python只检查#.coding和编码字符串,所以你可能回见到下面的声明方 ...

  5. 77.PS接收来自PL的按键中断

    本篇文章主要介绍外设(PL)产生的中断请求,在PS端进行处理. 在PL端通过按键产生中断,PS接受到之后点亮相应的LED. 本文所使用的开发板是zedboardPC 开发环境版本:Vivado 201 ...

  6. STL hashtable阅读记录

    unordered_map,unordered_set等相关内容总结: unordered_map和unordered_set是在开发过程中常见的stl数据结构.其本质是hashtable.在SGI_ ...

  7. CentOS中搭建Redis伪分布式集群【转】

    解压redis 先到官网https://redis.io/下载redis安装包,然后在CentOS操作系统中解压该安装包: tar -zxvf redis-3.2.9.tar.gz 编译redis c ...

  8. 制作一棵ztree

    我们在做web项目时,常会用到一些树形菜单.在此,我们利用ztree实现树形菜单的效果.zTree 是一个依靠 jQuery 实现的多功能 “树插件”.优异的性能.灵活的配置.多种功能的组合是 zTr ...

  9. HDU 2102 A计划(BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 题目大意:公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输 ...

  10. apache2.2控制目录文件访问设置

    1.apache2.2控制目录文件访问需求 红框可以访问,其他不能访问 2.apache2.2具体正则配置 <locationMatch ^/f/user/Panorama/81/581/(gr ...