[BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)
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 2Sample Output
2
1
3
1HINT
对于100%的数据,1≤N、M、K≤200,000。
2016.2.26提高时限至60s
Source
用LCT求出NTR数组,然后主席树在线查询即可,比较简洁巧妙。
不过是两个高级数据结构合在一起,而且不是嵌套,理论上很好写。
实际上犯了很多低级错误,而且非常难调,以后一定要慢点写代码。
- #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+主席树)的更多相关文章
- 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条边有贡献 ...
- 【BZOJ3514】Codechef MARCH14 GERALD07加强版 LCT+主席树
题解: 还是比较简单的 首先我们的思路是 确定起点 然后之后贪心的选择边(也就是越靠前越希望选) 我们发现我们只需要将起点从后向前枚举 然后用lct维护连通性 因为强制在线,所以用主席树记录状态就可以 ...
- bzoj3514 Codechef MARCH14 GERALD07加强版 lct预处理+主席树
Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1951 Solved: 746[Submi ...
- 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1288 Solved: 490 ...
- BZOJ3514: Codechef MARCH14 GERALD07加强版(LCT,主席树)
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密.接下来M ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT维护最大生成树 主席树
题面 考虑没有询问,直接给你一个图问联通块怎么做. 并查集是吧. 现在想要动态地做,那么应该要用LCT. 考虑新加进来一条边,想要让它能够减少一个联通块的条件就是现在边的两个端点还没有联通. 如果联通 ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树
自己独自想出来并切掉还是很开心的~ Code: #include <bits/stdc++.h> #define N 400005 #define inf 1000000000 #defi ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3514 题意概括 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. N ...
随机推荐
- Java读取大文件的高效率实现
1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 ...
- HDU 2159 FATE (dp)
题目链接 Problem Description 最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务.久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最 ...
- oracle链接指定实例
sqlplus /@ORACLE_SID as sysdba; 其中ORACLE_SID为具体的实例名称, 比如连接到orcl实例就执行命令: sqlplus /@orcl as sysdba; se ...
- SVMtrain的参数c和g的优化
SVMtrain的参数c和g的优化 在svm训练过程中,需要对惩罚参数c和核函数的参数g进行优化,选取最好的参数 知道测试集标签的情况下 是让两个参数c和g在某一范围内取离散值,然后,取测试集分类准确 ...
- Java-悲观锁和乐观锁
Java中的乐观锁与悲观锁: 1. Java中典型的synchronized就是一种悲观锁,也就是独占锁,不过JDK1.6之后对synchronized已经做了许多优化,也不能说是完全的悲观锁了: 2 ...
- golang之结构体和方法
结构体的定义 结构体是将零个或者多个任意类型的命令变量组合在一起的聚合数据类型.每个变量都叫做结构体的成员. 其实简单理解,Go语言的结构体struct和其他语言的类class有相等的地位,但是GO语 ...
- Mariadb 10.2中的json使用及应用场景思考
-- 创建示例表DROP TABLE IF EXISTS `t_base_user`;CREATE TABLE `t_base_user` ( `USER_ID` char(36) CHARACT ...
- 关于wordpress插件WP SMTP的邮箱设置
花了两天的时间把邮箱设置好了,把大概的步骤写下,放一下查到的资料. 1.去域名服务商那里添加MX记录 如下图的MX 2.测试主机是否禁用了mail()函数 参考链接wo ...
- Mysql学习之order by的工作原理
在你开发应用的时候,一定会经常碰到需要根据指定的字段排序来显示结果的需求.假设你要查询城市是“杭州”的所有人名字,并且按照姓名排序返回前 1000 个人的姓名.年龄. 查询语句为: ; 全字段排序 为 ...
- 【58沈剑架构系列】主从DB与cache一致性
本文主要讨论这么几个问题: (1)数据库主从延时为何会导致缓存数据不一致 (2)优化思路与方案 一.需求缘起 上一篇<缓存架构设计细节二三事>中有一个小优化点,在只有主库时,通过“串行化” ...