发现自己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. [转]C#中调用资源管理器(Explorer.exe)打开指定文件夹 + 并选中指定文件 + 调用(系统默认的播放类)软件(如WMP)打开(播放歌曲等)文件

    原文:http://www.crifan.com/csharp_call_explorer_to_open_destinate_folder_and_select_specific_file/ C#中 ...

  2. Bootstrap_下拉菜单

    在使用Bootstrap框架的下拉菜单时,必须调用Bootstrap框架提供的bootstrap.js文件. 一.普通下拉菜单 <div class="dropdown"&g ...

  3. LuaStudio 9.27 去10分钟退出暗桩板

    http://bbs.pediy.com/showthread.php?p=1428203#post1428203

  4. 后勤数据源增量队列Delta Queue(RSA7)中的增量更新区Delta Update、增量重复区Delta Repetition

    声明:原创作品,转载时请注明文章来自SAP师太技术博客:( 博/客/园www.cnblogs.com)www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. 用HttpSessionListener与HttpSessionBindingListener实现在线人数统计

    在线人数统计方面的实现,最初我的想法是,管理session,如果session销毁了就减少,如果登陆用户了就新增一个,但是如果是用户非法退出,如:未注销,关闭浏览器等,这个用户的session是管理不 ...

  6. XAF How to: 实现一个WCF Application Server 并配置它的客户端应用

    本主题描述了如何实现一个 WCF 中间层应用程序服务器及如何配置 XAF客户端连接到此服务器. 注意 本主题演示可以由解决方案向导自动生成的代码.执行操作时,如果你想要在现有的 XAF 解决方案中实现 ...

  7. sqlAlchemy 按DateTime字段的年或月进行group_by查询

    一.根据”create_date“查询每天的数据 1.查询2016年5月每天的数据 session.query(extract('day', User.create_date).label('day' ...

  8. JDK的安装与配置

    1.什么是JDK(Java Development Kit) 开发工具,javac及基础核心类 运行环境,java及基础核心类 2.目前Java平台的版本 JavaSE(Java Platform S ...

  9. leetcode-188 买卖股票4

    题目 给定一个数组表示股票每天的价格,最多交易k次,且手上最多只能拥有一支股票(即只能先卖出手上现有的股票再去购买新的股票),求最大的收益.     题目链接:买卖股票4     开始思路不清楚,参考 ...

  10. CSS样式汇总

    1. Overflow: 是否隐藏超出容器范围之外的内容,主要参数包括Hidden(隐藏),Auto(根据容器内容自动显示滚动条),scroll(显示滚动条,即使内容不超出容器范围,也会显示一个边框, ...