发现自己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. Windows下WebStorm使用SVN

    安装了phpstorm之后,想配置svn,结果在file->settings->Version Contorl->subversion->use conmand line cl ...

  2. ambari之hbase数据迁移

    一.hbase原理剖析 Base是一个构建在HDFS上的分布式列存储系统:HBase是基于Google BigTable模型开发的,典型的key/value系统:HBase是Apache Hadoop ...

  3. 原来MySQl就是这样工作的!

    一.MySQL简单介绍     MySQL是当今最流行的开源数据库管理系统,超过10亿的下载量足可以证明这点.MySQL以其速度.高可靠性.简单易用,广泛应用,一些大型企业也在逐渐应用,如:Faceb ...

  4. java高薪之路__007_反射

    参考地址: 1. http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html2. http://www.cnblogs.com/ ...

  5. spring data实现自定义的repository实现类,实现跟jpa联通

    如果你不想暴露那么多的方法,可以自己订制自己的Repository,还可以在自己的Repository里面添加自己使用的公共方法 当然更灵活的是自己写一个实现类,来实现自己需要的方法 1:写一个与接口 ...

  6. 将回车键转tab键

    //功能:将回车键转tab键$(function () {$('input:text:first').focus();var $enter = $("input[type=text],but ...

  7. intellij中编译报错: The packaging for this project did not assign a file to the build artifact

    原因是run configuration -> maven -> preject name -> Parameters -> command line中是install:ins ...

  8. zabbix3.0.4 部署之一 (简介)

    官方网站:http://www.zabbix.com/ 下载地址:http://www.zabbix.com/download.php zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视 ...

  9. 转<%%>、<%=%>、<%$%>、<%@%>的区别

    1. 未定义的命名空间前缀“xsd” 上周在项目开发中遇到这样的一个问题,在一个页面用到了自定义的Picker控件,在IE6.7.8.9以及IE10兼容模式下都没有任何问题,但是一换到IE10时已选择 ...

  10. <转>浏览器内核分类

    浏览器的种类成千上百,但所基于的内核,却没有几个.目前主流的浏览器内核主要为以下四种: 一.Trident内核,代表产品Internet Explorer说起Trident,很多人都会感到陌生,但提起 ...