发现自己Tarjan的板子有错误.发现可以用Map直接删去边,Get.

听说std是双连通、LCA、并查集、离线思想、用BIT维护dfs序和并查集维护LCA的动态缩点的好题

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <stack>
#define mp make_pair
#define pa pair<int,int>
#define pb push_back
#define fi first
#define se second
using namespace std;
inline void Get_Int(int &x)
{
x=; char ch=getchar(); int f=;
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();} x*=f;
}
inline void Put_Int(int x)
{
char ch[]; int top=;
if (x==) ch[++top]='';
while (x) ch[++top]=x%+'',x/=;
while (top) putchar(ch[top--]); putchar('\n');
}
//===================================================
const int Maxm=;
const int Maxn=;
const int Maxop=;
struct EDGE{int to,next;}edge[Maxm];
struct OP{int type,u,v;}Op[Maxop];
int head[Maxn],siz[Maxn],father[Maxn],top[Maxn],dep[Maxn],num[Maxn],sum[Maxn<<],clr[Maxn<<];
int Belong[Maxn],Low[Maxn],Dfn[Maxn],Ans[Maxn];
int Stack[Maxn];
int stamp,Stamp,cnt,scc,apex,Q,n,m,u,v;
bool vis[Maxn];
map<pa,bool> Edge;
vector<pa> V;
set <pa> S;
inline void Add(int u,int v)
{edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}
inline int Max(int x,int y) {return x>y?x:y;}
inline int Min(int x,int y) {return x>y?y:x;}
inline void Build_G()
{
map<pa,bool>::iterator it;
for (it=Edge.begin();it!=Edge.end();it++)
if (it->se)
Add(it->fi.fi,it->fi.se);
}
inline void Clear_G()
{
map<pa,bool>::iterator it;
for (it=Edge.begin();it!=Edge.end();it++)
if (it->se) it->se=false;
}
//================================================= void Dfs1(int u)
{
vis[u]=true; siz[u]=;
for (int i=head[u];i!=-;i=edge[i].next)
if (!vis[edge[i].to])
{
father[edge[i].to]=u;
dep[edge[i].to]=dep[u]+;
Dfs1(edge[i].to);
siz[u]+=siz[edge[i].to];
}
}
void Dfs2(int u,int chain)
{
num[u]=++stamp; top[u]=chain; vis[u]=true; int k=;
for (int i=head[u];i!=-;i=edge[i].next)
if (!vis[edge[i].to] && (siz[edge[i].to]>siz[k] || k==)) k=edge[i].to;
if (k==) return;
Dfs2(k,chain);
for (int i=head[u];i!=-;i=edge[i].next)
if (!vis[edge[i].to] && edge[i].to!=k) Dfs2(edge[i].to,edge[i].to);
} inline int Lca(int u,int v)
{
while (true)
{
if (top[u]==top[v]) return dep[u]>dep[v]?v:u;
if (dep[top[u]]>dep[top[v]]) u=father[top[u]]; else v=father[top[v]];
}
}
//================================================== inline void push_up(int o) {sum[o]=sum[o<<]+sum[o<<|];}
inline void Clr(int o) {clr[o]=; sum[o]=;}
inline void push_down(int o) {if (clr[o]) Clr(o<<),Clr(o<<|); clr[o]=;}
void Modify(int o,int l,int r,int p,int q)
{
if (l==p && r==q)
{
sum[o]=;
clr[o]=;
return;
}
push_down(o);
int mid=(l+r)>>;
if (q<=mid) Modify(o<<,l,mid,p,q);
if (p>=mid+) Modify(o<<|,mid+,r,p,q);
if (p<=mid && q>=mid+) Modify(o<<,l,mid,p,mid),Modify(o<<|,mid+,r,mid+,q);
push_up(o);
}
int Query(int o,int l,int r,int p,int q)
{
if (l==p && r==q) return sum[o];
push_down(o);
int mid=(l+r)>>;
if (q<=mid) return Query(o<<,l,mid,p,q);
if (p>=mid+) return Query(o<<|,mid+,r,p,q);
if (p<=mid && q>=mid+) return Query(o<<,l,mid,p,mid)+Query(o<<|,mid+,r,mid+,q);
}
void Build(int o,int l,int r)
{
if (l==r)
{
sum[o]=;
return;
}
int mid=(l+r)>>;
Build(o<<,l,mid),Build(o<<|,mid+,r);
push_up(o);
} //=================================================
void Tree_Modify(int u,int v)
{
while (top[u]!=top[v])
{
Modify(,,scc,num[top[u]],num[u]);
u=father[top[u]];
}
Modify(,,scc,num[v],num[u]);
}
int Tree_Query(int u,int v)
{
int ret=; while (top[u]!=top[v])
{
ret+=Query(,,scc,num[top[u]],num[u]);
u=father[top[u]];
}
ret+=Query(,,scc,num[v],num[u]);
return ret;
}
//=================================================
void Tarjan(int u,int fa)
{
Low[u]=Dfn[u]=++Stamp; Stack[++apex]=u;
for(int i=head[u];i!=-;i=edge[i].next)
if (edge[i].to!=fa)
{
int v=edge[i].to;
if(!Dfn[v])
{
Tarjan(v,u);
Low[u]=Min(Low[u],Low[v]);
if(Low[v]>Dfn[u])
{
scc++;
while(true) {int x=Stack[apex--]; Belong[x]=scc; if(x==v)break;}
}
}
else Low[u]=Min(Low[u],Dfn[v]);
}
if(fa<)
{
scc++;
while(true){int x=Stack[apex--]; Belong[x]=scc; if(x==u)break;}
}
}
//================================================= int main()
{
//freopen("c.in","r",stdin);
Get_Int(n),Get_Int(m);
for (int i=;i<=m;i++)
Get_Int(u),Get_Int(v),Edge[mp(u,v)]=true,Edge[mp(v,u)]=true; for (Q=;;Q++)
{
Get_Int(Op[Q].type); if (Op[Q].type==-) break;
Get_Int(Op[Q].u),Get_Int(Op[Q].v);
if (Op[Q].type==) Edge[mp(Op[Q].u,Op[Q].v)]=false,Edge[mp(Op[Q].v,Op[Q].u)]=false;
}
Q--;
stamp=Stamp=cnt=;
memset(head,-,sizeof(head));
memset(vis,false,sizeof(vis));
memset(Low,,sizeof(Low));
memset(Dfn,,sizeof(Dfn)); Build_G();
Tarjan(,-);
Clear_G();
for (int i=;i<=n;i++)
for (int j=head[i];j!=-;j=edge[j].next)
if (Belong[i]!=Belong[edge[j].to])
{
if (S.count(mp(Belong[i],Belong[edge[j].to]))==) continue;
S.insert(mp(Belong[i],Belong[edge[j].to]));
S.insert(mp(Belong[edge[j].to],Belong[i]));
V.pb(mp(Belong[i],Belong[edge[j].to]));
V.pb(mp(Belong[edge[j].to],Belong[i]));
} memset(head,-,sizeof(head));cnt=;
for (int i=;i<V.size();i++) Add(V[i].fi,V[i].se);
father[]=;dep[]=;
memset(vis,false,sizeof(vis)),Dfs1();
memset(vis,false,sizeof(vis)),Dfs2(,);
Build(,,scc);
for (int i=Q;i>=;i--)
{
int p=Belong[Op[i].u],q=Belong[Op[i].v];
if (Op[i].type==)
{
if (p==q) continue;
int t=Lca(p,q);
if (t==p)
{
int k=;
for (int j=head[t];j!=-;j=edge[j].next)
if (Lca(edge[j].to,q)==edge[j].to && father[t]!=edge[j].to) {k=edge[j].to; break;} Tree_Modify(q,k);
continue;
} if (t==q)
{
int k=;
for (int j=head[t];j!=-;j=edge[j].next)
if (Lca(edge[j].to,p)==edge[j].to && father[t]!=edge[j].to) {k=edge[j].to; break;}
Tree_Modify(p,k);
continue;
}
int r,s;
for (int j=head[t];j!=-;j=edge[j].next)
if (Lca(edge[j].to,p)==edge[j].to && father[t]!=edge[j].to) {r=edge[j].to; break;}
for (int j=head[t];j!=-;j=edge[j].next)
if (Lca(edge[j].to,q)==edge[j].to && father[t]!=edge[j].to) {s=edge[j].to; break;}
Tree_Modify(p,r),Tree_Modify(q,s);
} else
if (Op[i].type==)
{
if (p==q) {Ans[i]=; continue;}
int t=Lca(p,q);
if (t==p)
{
int k=;
for (int j=head[t];j!=-;j=edge[j].next)
if (Lca(edge[j].to,q)==edge[j].to && father[t]!=edge[j].to) {k=edge[j].to; break;}
Ans[i]=Tree_Query(q,k);
continue;
}
if (t==q)
{
int k=;
for (int j=head[t];j!=-;j=edge[j].next)
if (Lca(edge[j].to,p)==edge[j].to && father[t]!=edge[j].to) {k=edge[j].to; break;}
Ans[i]=Tree_Query(p,k);
continue;
} int r,s;
for (int j=head[t];j!=-;j=edge[j].next)
if (Lca(edge[j].to,p)==edge[j].to && father[t]!=edge[j].to) {r=edge[j].to; break;}
for (int j=head[t];j!=-;j=edge[j].next)
if (Lca(edge[j].to,q)==edge[j].to && father[t]!=edge[j].to) {s=edge[j].to; break;}
Ans[i]=Tree_Query(p,r)+Tree_Query(q,s);
}
}
for (int i=;i<=Q;i++)
if (Op[i].type==) Put_Int(Ans[i]);
return ;
}

傻逼树剖280+系列

BZOJ 1969 树链剖分+Tarjan缩点的更多相关文章

  1. BZOJ_4326_[NOIP2015]_运输计划_(二分+LCA_树链剖分/Tarjan+差分)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=4326 给出一棵带有边权的树,以及一系列任务,任务是从树上的u点走到v点,代价为u到v路径上的权 ...

  2. BZOJ 4326 树链剖分+二分+差分+记忆化

    去年NOIP的时候我还不会树链剖分! 还是被UOJ 的数据卡了一组. 差分的思想还是很神啊! #include <iostream> #include <cstring> #i ...

  3. BZOJ 1036 && 树链剖分

    还是太弱啊..各种数据结构只听过名字却没有一点概念..树链剖分也在这个范畴..今天来进一步深化一下教育改革推进全民素质提高. 性质 忘了在哪里看到的一篇blog有一句话讲得非常好,树链剖分不是一种数据 ...

  4. bzoj 3083 树链剖分

    首先我们先将树提出一个根变成有根树,那么我们可以通过树链剖分来实现对于子树的最小值求解,那么按照当前的根和询问的点的相对位置关系我们可以将询问变成某个子树和或者除去某颗子树之后其余的和,前者直接询问区 ...

  5. bzoj 2243 树链剖分

    2013-11-19 16:21 原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=2243 树链剖分,用线段树记录该区间的颜色段数,左右端点颜 ...

  6. bzoj 4196 树链剖分 模板

    [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2135  Solved: 1232[Submit][Status][D ...

  7. BZOJ 4811 树链剖分+线段树

    思路: 感觉这题也可神了.. (还是我太弱) 首先发现每一位不会互相影响,可以把每一位分开考虑,然后用树链剖分或者LCT维护这个树 修改直接修改,询问的时候算出来每一位填0,1经过这条链的变换之后得到 ...

  8. BZOJ 4034 树链剖分

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4034 题意:中文题面 思路:树链剖分入门题. 剖分后就是一个简单的区间更新和区间求和问题. ...

  9. BZOJ 2286 树链剖分+DFS序+虚树+树形DP

    第一次学习虚树,就是把无关的点去掉.S里维护一条链即可. #include <iostream> #include <cstring> #include <cstdio& ...

随机推荐

  1. noi 8780 拦截导弹

    题目链接: http://noi.openjudge.cn/ch0206/8780/ LDS http://paste.ubuntu.com/23402528/

  2. R之data.table -melt/dcast(数据合并和拆分)

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 30.0px "Helvetica Neue"; color: #323333 } p. ...

  3. ace_admin_1.3.1 wysiwyg 工具条下拉出不来

    试了很久才知道是因为<script src="__PUBLIC__/assets/js/bootstrap.min.js"></script>  这个js加 ...

  4. 关于JS中apply方法的基本理解

    最近研究OpenLayers源码时,发现其中使用了比较多的apply方法,对其也是很不明白.于是上网经过多方面了解以及自己细细体会后,终于算是基本明白是其干什么的了,这里分享下.apply方法的造型是 ...

  5. 关于web2py外网访问,图形界面不显示等问题的解决办法

    首先系统版本是ubuntu 15.04,系统默认安装了两个版本的python, sudo python web2py.py 默认会调用python2.7版本来执行 会提示 pydo@planpls:/ ...

  6. iOS Question

    Q1: dyld: Library not loaded: @rpath/libswiftCore.dylib 1. 退出 Xcode2. 重启电脑3. 找到 这个 DerivedData 文件夹 删 ...

  7. window.onload()和$(function(){});的区别

    1.window.onload必须等到页面中所有元素加载完之后才会执行(包括图片.视频等)而$(function(){});是在结构绘制完毕之后执行,二者的执行时机是不同的,一般来说后者会首先执行 2 ...

  8. t检验

    例子:以往通过大规模调查已知某地新生儿出生体重为3.30kg.从该地难产儿中随机抽取35名新生儿作为研究样本,平均出生体重为3.42kg,标准差为0.40kg. 问该地难产儿出生体重是否与一般新生儿体 ...

  9. Matlab 霍夫变换 ( Hough Transform) 直线检测

    PS:好久没更新,因为期末到了,拼命复习中.复习久了觉得枯燥,玩玩儿霍夫变换直线检测 霍夫变换的基本原理不难,即便是初中生也很容易理解(至少在直线检测上是这样子的). 霍夫变换直线检测的基本原理:(不 ...

  10. redis.conf 配置详解 (转)

    # Redis 配置文件 # 当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其转换方式如下(不区分大小写)## 1k => 1000 bytes# 1kb => ...