萌新第一天学 OI,这题太难,求调!玄关。
查看原帖
萌新第一天学 OI,这题太难,求调!玄关。
638491
Illus1onary_Real1ty楼主2024/8/3 20:12

过了样例,但是 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;
} 
2024/8/3 20:12
加载中...