题解 [CF786D] Rap God / 谣音

传送门

数据水了,\(O(nq)\) 过了,我鸽了

我跟 f____u 打赌我这篇博会不会被踩爆

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define fir first
#define sec second
#define pb push_back
#define ll long long
//#define int long long

int n, m;
char c[10];
vector<pair<int, char>> to[N];
// int head[N], ecnt;
// struct edge{int to, next; char val;}e[N<<1];
// inline void add(int s, int t, char w) {e[++ecnt]={t, head[s], w}; head[s]=ecnt;}

namespace force{
	pair<int, int> q[N];
	char sta[N], tem[N], back[N];
	int dep[N], siz[N], fa[N], tim[N], top, tot, l, r;
	void dfs(int u, int pa) {
		fa[u]=pa; siz[u]=1;
		for (auto& it:to[u]) if (it.fir!=pa) {
			dep[it.fir]=dep[u]+1;
			back[it.fir]=it.sec;
			dfs(it.fir, u);
			siz[u]+=siz[it.fir];
		}
		// for (int i=head[u],v; ~i; i=e[i].next) if ((v=e[i].to)!=pa) {
		// 	dep[v]=dep[u]+1;
		// 	back[v]=e[i].val;
		// 	dfs(v, u);
		// 	siz[u]+=siz[v];
		// }
	}
	void getpath(int u, int v) {
		top=tot=0;
		while (u!=v) {
			if (dep[u]>dep[v]) {
				sta[++top]=back[u];
				u=fa[u];
			}
			else {
				tem[++tot]=back[v];
				v=fa[v];
			}
		}
		while (tot) sta[++top]=tem[tot--];
	}
	void solve() {
		dfs(1, 0);
		for (int i=1,x,y; i<=m; ++i) {
			scanf("%d%d", &x, &y);
			ll ans=0; getpath(x, y);
			q[l=r=1]={x, 1};
			while (l<=r) {
				int u=q[l].fir, now=q[l].sec; ++l;
				tim[u]=i;
				for (auto& v:to[u]) if (tim[v.fir]!=i) {
					if (v.sec<sta[now]) {
						if (fa[v.fir]==u) ans+=siz[v.fir];
						else ans+=siz[1]-siz[u];
					}
					else if (v.sec==sta[now]&&now!=top) {
						++ans;
						q[++r]={v.fir, now+1};
					}
				}
				// for (int j=head[u],v; ~j; j=e[j].next) if (tim[v=e[j].to]!=i) {
				// 	if (e[j].val<sta[now]) {
				// 		if (fa[v]==u) ans+=siz[v];
				// 		else ans+=siz[1]-siz[u];
				// 	}
				// 	else if (e[j].val==sta[now]&&now!=top) {
				// 		++ans;
				// 		q[++r]={v, now+1};
				// 	}
				// }
			}
			printf("%lld\n", ans);
		}
	}
}

signed main()
{
	// freopen("music.in", "r", stdin);
	// freopen("music.out", "w", stdout);

	scanf("%d%d", &n, &m);
	// memset(head, -1, sizeof(head));
	for (int i=1,u,v; i<n; ++i) {
		scanf("%d%d%s", &u, &v, c);
		to[u].pb({v, *c}), to[v].pb({u, *c});
		// add(u, v, *c), add(v, u, *c);
	}
	force::solve();

	return 0;
}
posted @ 2022-08-01 21:44  Administrator-09  阅读(3)  评论(0编辑  收藏  举报