题目大意:

给定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+划分树的更多相关文章

  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. [BZOJ 3514]Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES)

    [BZOJ3514] Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES) 题意 \(N\) 个点 \(M\) 条边的无向图,\(K\) 次询问保 ...

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

    题意 \(N\) 个点 \(M\) 条边的无向图,询问保留图中编号在 \([l,r]\) 的边的时候图中的联通块个数. \(K\) 次询问强制在线. \(1\le N,M,K \le 200,000\ ...

  5. BZOJ 3514 Codechef MARCH14 GERALD07加强版

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3514 题意:给出一个图m条边.每次询问只加入编号在区间[L,R]之内的边有多少连通 ...

  6. 【刷题】BZOJ 3514 Codechef MARCH14 GERALD07加强版

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

  7. BZOJ 3514: Codechef MARCH14 GERALD07加强版 (LCT维护最大生成树+主席树)

    题意 给出nnn个点,mmm条边.多次询问,求编号在[l,r][l,r][l,r]内的边形成的联通块的数量,强制在线. 分析 LCTLCTLCT维护动态最大生成树,先将每条边依次加进去,若形成环就断掉 ...

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

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

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

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

随机推荐

  1. 第16课 “远程 Git文档库” 的基础操作

    16-1  “远程Git文档库”  的功能 如果  “本地Git文档库” 和  “远程Git文档库”  是存储在不同的计算机中,它们之前传送数据可以通过HTTP/HTTPS.SSH.GIT proto ...

  2. strcpy自实现

    为了避免strcpy源串覆盖问题(P220),自实现strcpy. #include <stdio.h> #include <string.h> #include <as ...

  3. 【Codeforces】Codeforces Round #373 (Div. 2)

    B. Anatoly and Cockroaches Anatoly lives in the university dorm as many other students do. As you kn ...

  4. jquery插件之倒计时-团购秒杀

      1.1 帮助文档关键字 倒计时 秒杀 timer 1.2.  使用场景 这样的倒计时在购物网站中会经常使用到,比如秒杀,限时抢购,确认收货倒计时. 这个功能并不难实现,就是利用js的定时执行,搜了 ...

  5. Pjax无刷新跳转页面实现,支持超链接与表单提交

    什么是pjax? 当你点击一个站内的链接的时候,不是做页面跳转,而是只是站内页面刷新.这样的用户体验,比起整个页面都闪一下来说, 好很多. 其中有一个很重要的组成部分, 这些网站的ajax刷新是支持浏 ...

  6. CDR服装设计-旗袍款式图

    在服装行业中的服装款式设计.图案设计和面料设计等方面,CorelDRAW是一款常用绘图设计软件,用CorelDRAW绘制款式图比手绘更容易表达服装结构.比例.图案.色彩等要素,服装款图主要目的是为了更 ...

  7. 【转】虚拟化(三):vsphere套件的安装注意及使用

    vsphere套件里面主要的组件有esxi.vcenter server .vsphere client和vsphere web client. vcenter做为vsphere套件的核心管理成员之一 ...

  8. CF482D Random Function and Tree 树形DP + 思维 + 神题

    Code: #include<bits/stdc++.h> #define ull unsigned long long #define MOD 1000000007 #define ll ...

  9. vue中引入json数据,不用本地请求

    1.我的项目结构,需要在Daily.vue中引入daily.js中的json数据 2.把json数据放入一个js文件中,用exports导出,vscode的json格式太严格了,很多数据,调了一个多小 ...

  10. 15.3 Task 语法和语义

    15.3.1 声明异步方法和返回类型 async static void GetStringAsync() { using (var client = new HttpClient()) { Task ...