BZOJ 3514 Codechef MARCH14 GERALD07加强版 Link-Cut-Tree+划分树
题目大意:
给定n个点m条边的无向图。求问当图中仅仅有【编号在[l,r]区间内】的边存在时图中的联通块个数 强制在线
注意联通块是指联通了就是同一块,不是Tarjan求的那种块
看到这题的那一刻我就想小便有木有0.0 这尼玛怎么做?可持久化并查集? 暴力? 分块乱搞? 。。。
后来看了HZWER大神的博客才知道这样的巧妙的算法0.0 太强大了
直接复制wulala的题解 讲得非常清楚 不累述了
wulala
葱娘说这是一个非常巧妙的题。。
有一个比較猎奇的做法:首先把边依次加到图中,若当前这条边与图中的边形成了环,那么把这个环中最早加进来的边弹出去
并将每条边把哪条边弹了出去记录下来: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,我反正是用的函数式线段树
这个真是太强大了0.0 假设这条边踢掉的最早的边也在[l,r]区间内 那么增加这条边一定对图的连通性没有影响 否则就会连接两个联通块 导致ans--
至于求l~r中有多少边的ntr小于l我用的是划分树 蒟蒻不会写主席树肿莫破。。
。
ntr。寝取り,果然是个够劲的名字。
。
。 于是为了保持这样的美好的意境我也牺牲了划分树中的a数组改成了ntr。。
。
把这个美好的意境传承下去吧。。
。
另外这题有自环 自环的话相当于自己ntr自己 直接记录ntr之后就返回好了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 200200
#define INF 2147483647
using namespace std;
struct edges{
int x,y;
}e[M];
struct abcd{
abcd *fa,*ls,*rs;
int num,minnum;
bool rev_mark;
abcd(int x);
void Reverse();
void Push_Up();
void Push_Down();
}*null=new abcd(INF),*tree[M<<1];
abcd :: abcd(int x)
{
fa=ls=rs=null;
num=minnum=x;
rev_mark=0;
}
void abcd :: Reverse()
{
rev_mark^=1;
swap(ls,rs);
}
void abcd :: Push_Up()
{
minnum=min(ls->minnum,rs->minnum);
minnum=min(minnum,num);
}
void abcd :: Push_Down()
{
if(fa->ls==this||fa->rs==this)
fa->Push_Down();
if(rev_mark)
{
ls->Reverse();
rs->Reverse();
rev_mark=0;
}
}
void Zig(abcd *x)
{
abcd *y=x->fa;
y->ls=x->rs;
x->rs->fa=y;
x->rs=y;
x->fa=y->fa;
if(y==y->fa->ls)
y->fa->ls=x;
else if(y==y->fa->rs)
y->fa->rs=x;
y->fa=x;
y->Push_Up();
}
void Zag(abcd *x)
{
abcd *y=x->fa;
y->rs=x->ls;
x->ls->fa=y;
x->ls=y;
x->fa=y->fa;
if(y==y->fa->ls)
y->fa->ls=x;
else if(y==y->fa->rs)
y->fa->rs=x;
y->fa=x;
y->Push_Up();
}
void Splay(abcd *x)
{
x->Push_Down();
while(x->fa->ls==x||x->fa->rs==x)
{
abcd *y=x->fa,*z=y->fa;
if(x==y->ls)
{
if(y==z->ls)
Zig(y);
Zig(x);
}
else
{
if(y==z->rs)
Zag(y);
Zag(x);
}
}
x->Push_Up();
}
void Access(abcd *x)
{
abcd *y=null;
while(x!=null)
{
Splay(x);
x->rs=y;
x->Push_Up();
y=x;
x=x->fa;
}
}
abcd* Find_Root(abcd *x)
{
while(x->fa!=null)
x=x->fa;
return x;
}
void Move_To_Root(abcd *x)
{
Access(x);
Splay(x);
x->Reverse();
}
void Link(abcd *x,abcd *y)
{
Move_To_Root(x);
x->fa=y;
}
void Cut(abcd *x,abcd *y)
{
Move_To_Root(x);
Access(y);
Splay(y);
x->fa=null;
y->ls=null;
y->Push_Up();
}
int Query(abcd *x,abcd *y)
{
Move_To_Root(x);
Access(y);
Splay(y);
return y->minnum;
}
int n,m,q,type,ans;
int ntr[M],b[M],c[M],s[20][M];
void Insert(int p)
{
if(e[p].x==e[p].y)
{
ntr[p]=p;
return ;
}
abcd *x=tree[e[p].x],*y=tree[e[p].y];
if( Find_Root(x)==Find_Root(y) )
{
int temp=Query(x,y);
ntr[p]=temp;
Cut(tree[n+temp],tree[e[temp].x]);
Cut(tree[n+temp],tree[e[temp].y]);
free(tree[n+temp]);
}
tree[n+p]=new abcd(p);
Link(tree[n+p],tree[e[p].x]);
Link(tree[n+p],tree[e[p].y]);
}
void Build_Tree(int l,int r,int dpt)
{
int i,mid=l+r>>1;
int l1=l,l2=mid+1;
int left=mid-l+1;
if(l==r)
return ;
for(i=l;i<=r;i++)
left-=(ntr[i]<c[mid]);
for(i=l;i<=r;i++)
{
if(ntr[i]<c[mid]||ntr[i]==c[mid]&&left)
b[l1++]=ntr[i],s[dpt][i]=(i==l?1:s[dpt][i-1]+1),left-=(ntr[i]==c[mid]);
else
b[l2++]=ntr[i],s[dpt][i]=(i==l?0:s[dpt][i-1]);
}
memcpy( ntr+l , b+l , sizeof(ntr[0])*(r-l+1) );
Build_Tree(l,mid,dpt+1);
Build_Tree(mid+1,r,dpt+1);
}
int Get_Ans(int l,int r,int dpt,int x,int y,int val)
{
int mid=l+r>>1;
int l1=(x==l?0:s[dpt][x-1]),l2=s[dpt][y];
if(x>y)
return 0;
if(l==r)
return ntr[mid]<val;
if(val<=c[mid])
return Get_Ans(l,mid,dpt+1,l+l1,l+l2-1,val);
else
return l2-l1+Get_Ans(mid+1,r,dpt+1,(mid+1)+(x-l-l1),(mid+1)+(y-l+1-l2)-1,val);
}
int main()
{
int i,x,y;
cin>>n>>m>>q>>type;
for(i=1;i<=n;i++)
tree[i]=new abcd(INF);
for(i=1;i<=m;i++)
scanf("%d%d",&e[i].x,&e[i].y),Insert(i);
memcpy(c+1,ntr+1,sizeof(c[0])*m);
sort(c+1,c+m+1);
Build_Tree(1,m,0);
for(i=1;i<=q;i++)
{
scanf("%d%d",&x,&y);
x^=ans*type;y^=ans*type;
ans=n-Get_Ans(1,m,0,x,y,x);
printf("%d\n", ans );
}
}
BZOJ 3514 Codechef MARCH14 GERALD07加强版 Link-Cut-Tree+划分树的更多相关文章
- 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条边有贡献 ...
- [BZOJ 3514]Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES)
[BZOJ3514] Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES) 题意 \(N\) 个点 \(M\) 条边的无向图,\(K\) 次询问保 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版(LCT + 主席树)
题意 \(N\) 个点 \(M\) 条边的无向图,询问保留图中编号在 \([l,r]\) 的边的时候图中的联通块个数. \(K\) 次询问强制在线. \(1\le N,M,K \le 200,000\ ...
- BZOJ 3514 Codechef MARCH14 GERALD07加强版
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3514 题意:给出一个图m条边.每次询问只加入编号在区间[L,R]之内的边有多少连通 ...
- 【刷题】BZOJ 3514 Codechef MARCH14 GERALD07加强版
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版 (LCT维护最大生成树+主席树)
题意 给出nnn个点,mmm条边.多次询问,求编号在[l,r][l,r][l,r]内的边形成的联通块的数量,强制在线. 分析 LCTLCTLCT维护动态最大生成树,先将每条边依次加进去,若形成环就断掉 ...
- 【bzoj3514】Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树
题目描述 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 输入 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密.接下来M行,代表图中的每条边 ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树
自己独自想出来并切掉还是很开心的~ Code: #include <bits/stdc++.h> #define N 400005 #define inf 1000000000 #defi ...
随机推荐
- Alignment(dp)
http://poj.org/problem?id=1836 求两遍最长上升子序列,顺序求一遍,逆序求一遍. #include <stdio.h> #include <string. ...
- JS判断浏览器类型和详细区分IE各版本浏览器
今天用到JS判断浏览器类型,于是就系统整理了一下,便于后期使用. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ...
- thinkphp 日志记录
日志记录\ThinkPHP\Lib\Think\Core\Log.class.php 1.可以在config.php中进行设置,默认为关闭状态. 'APP_DEBUG' => true 打开\T ...
- ASP.NET Core 多环境
ASP.NET Core 支持在多个环境中管理应用程序,如开发(Development),预演(Staging)和生产(Production).环境变量用来指示应用程序正在运行的环境,允许应用程序适当 ...
- 有关css的选择器优先级以及父子选择器
css,又称样式重叠表,如今的网页的样式基本是div+css写出来的,功能十分强大,要想在html文件中引入css文件需要在<head></head>标签内输入一行:<l ...
- RFC1867 HTTP file upload
RFC1867 HTTP file upload RFC1867 is the standard definition of that "Browse..." button tha ...
- (转)用JS实现表格中隔行显示不同颜色
用JS实现表格中隔行显示不同颜色 第一种: <style> tr{bgColor:expression( this.bgColor=((this.rowIndex)%2==0 )? ...
- 1.0 windows10系统安装步骤(1)
1.0 windows10系统安装步骤(1) 根据自己对笔记本系统的折腾,为了方便他人系统的安装,故总结笔记本系统的安装步骤 目录: 1.0 [windows10系统安装步骤(1)] 2.0 Linu ...
- PAC学习理论:机器学习那些事
参考翻译,有大量删除和修改,如有异议,请拜访原文.一定要看英文原文!!!. 本文转载于:深度译文:机器学习那些事 英文[原题]A Few Useful Things to Know About Mac ...
- 安卓桌布显示的dip和px
安卓程序设计界面显示设置图像大小,在layout.xml里面有dip和px选项,dip为 什么 暂时还不知道,或许是设计桌布的设定像素比率,px为像素值: 比如我的手机是 Lenovo K920,屏幕 ...