过了样例,但是 WA 0 pts。
码风良好,代码简短小清新(
附代码:
#include <bits/stdc++.h>
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
const int N = 1e5 + 10;
int n, m, qt = 0, mt = 0, u[N], v[N], op[N], x[N], y[N];
int dfncnt = 0, dfn[N], low[N], cut[N];
int sc = 0, vis[N], scc[N];
map<pii, int> e;
vector<int> gt[N];
struct Edge{
int to, id;
Edge() {}
Edge(int to_, int id_){
to = to_;
id = id_;
}
};
vector<Edge> g[N];
void Tarjan(int u, int pre){
dfn[u] = low[u] = ++dfncnt;
for (auto e : g[u]){
int to = e.to;
int side = e.id;
if (side == pre)
continue;
if (!dfn[to]){
Tarjan(to, side);
low[u] = min(low[u], low[to]);
if (low[to] > dfn[u])
cut[side] = 1;
}else
low[u] = min(low[u], dfn[to]);
}
}
void Build_SCC(int u){
if (vis[u])
return;
vis[u] = 1;
scc[u] = sc;
for (auto e : g[u]){
int to = e.to;
int side = e.id;
if (cut[side])
continue;
Build_SCC(to);
}
}
int fa[N], depth[N], sz[N], hson[N], top[N], rk[N];
void DFS1(int u, int fno){
sz[u] = 1;
fa[u] = fno;
depth[u] = depth[fno] + 1;
for (auto to : gt[u]){
if (to == fno)
continue;
DFS1(to, u);
sz[u] += sz[to];
if (!hson[u] || sz[to] > sz[hson[u]])
hson[u] = to;
}
}
void DFS2(int u, int tp){
top[u] = tp;
dfn[u] = ++dfncnt;
rk[dfncnt] = u;
if (hson[u])
DFS2(hson[u], tp);
for (auto to : gt[u]){
if (to == fa[u] || to == hson[u])
continue;
DFS2(to, to);
}
}
int ans[N];
struct Segment_Tree{
#define lson rt<<1,l,md
#define rson rt<<1|1,md+1,r
static const int MR = 1e5 + 10;
int xds[MR << 2], tag[MR << 2];
void Push_Up(int rt){
xds[rt] = xds[rt << 1] + xds[rt << 1 | 1];
}
void Push_Tag(int rt){
xds[rt] = 0;
tag[rt] = 1;
}
void Push_Down(int rt){
if (tag[rt]){
Push_Tag(rt << 1);
Push_Tag(rt << 1 | 1);
tag[rt] = 0;
}
}
void Build(int rt, int l, int r){
if (l == r){
if (l != 1)
xds[rt] = 1;
return;
}
int md = (l + r) >> 1;
Build(lson);
Build(rson);
Push_Up(rt);
}
void Update(int rt, int l, int r, int x, int y){
if (x <= l && r <= y){
Push_Tag(rt);
return;
}
Push_Down(rt);
int md = (l + r) >> 1;
if (x <= md)
Update(lson, x, y);
if (y > md)
Update(rson, x, y);
Push_Up(rt);
}
int Query(int rt, int l, int r, int x, int y){
if (x <= l && r <= y)
return xds[rt];
Push_Down(rt);
int md = (l + r) >> 1;
int res = 0;
if (x <= md)
res += Query(lson, x, y);
if (y > md)
res += Query(rson, x, y);
return res;
}
}sgt;
void Update_Tree(int x, int y){
while (top[x] != top[y]){
if (depth[top[x]] < depth[top[y]])
swap(x, y);
sgt.Update(1, 1, n, dfn[top[x]], dfn[x]);
x = fa[top[x]];
}
if (depth[x] > depth[y])
swap(x, y);
if (x != y)
sgt.Update(1, 1, n, dfn[x] + 1, dfn[y]);
}
int Query_Tree(int x, int y){
int res = 0;
while (top[x] != top[y]){
if (depth[top[x]] < depth[top[y]])
swap(x, y);
res += sgt.Query(1, 1, n, dfn[top[x]], dfn[x]);
x = fa[top[x]];
}
if (depth[x] > depth[y])
swap(x, y);
if (x != y)
res += sgt.Query(1, 1, n, dfn[x] + 1, dfn[y]);
return res;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= m; i++)
cin >> u[i] >> v[i];
while (true){
qt++;
cin >> op[qt];
if (op[qt] == -1){
qt--;
break;
}else{
cin >> x[qt] >> y[qt];
if (op[qt] == 0){
e[mp(x[qt], y[qt])] = 1;
e[mp(y[qt], x[qt])] = 1;
}
}
}
for (int i = 1; i <= m; i++){
if (e.count(mp(u[i], v[i])))
continue;
++mt;
g[u[i]].push_back(Edge(v[i], mt));
g[v[i]].push_back(Edge(u[i], mt));
}
Tarjan(1, 0);
for (int i = 1; i <= n; i++)
if (!vis[i]){
sc++;
Build_SCC(i);
}
//for (int i = 1; i <= n; i++)
//cout << scc[i] << " " ;
//cout << endl;
for (int i = 1; i <= n; i++)
for (auto e : g[i]){
int u = e.to;
if (scc[u] == scc[i])
continue;
gt[scc[i]].push_back(scc[u]);
}
for (int i = 1; i <= qt; i++){
x[qt] = scc[x[qt]];
y[qt] = scc[y[qt]];
}
DFS1(1, 0);
dfncnt = 0;
DFS2(1, 0);
sgt.Build(1, 1, n);
for (int i = qt; i >= 1; i--){
if (op[i] == 0)
Update_Tree(x[i], y[i]);
else{
if (x[i] != y[i])
ans[i] = Query_Tree(x[i], y[i]);
}
}
for (int i = 1; i <= qt; i++)
if (op[i] == 1)
cout << ans[i] << endl;
return 0;
}