列表

详情


NC222507. Elomountains

描述

世界边缘山脉有一座最高峰,名为艾洛峰。除了艾洛峰外,还有其它n座山峰。
Megumi公司编号了这n+1座山峰。艾洛峰编号为0,另外n座山峰的编号为1-n。
建设旅游路线,最简单的方法是在山峰之间架设滑索。
为了节省能源,滑索是单向的。从高处的山峰出发,滑到低处的山峰。
为了方便指路,每条滑索都染了色。起点相同的滑索,颜色不同。
描述一条滑索需要三个参数:起点u、终点v和颜色c。
布丁架设了n条滑索。使得从艾洛峰出发,到达其它任意一座山峰,有且仅有一条路。
探路者机器人mavn负责验收。他记录了到达每座山峰,路上依次经过颜色形成的序列。
到达第x座山峰的路,形成的颜色序列记作arr_x
mavn需要汇报,对于每座山峰的颜色序列,被记录过的次数。
“是谁在滑索上飞行?我!”但mavn想去旅游,把记录和这个问题丢给了你。
为了更好地描述问题,对于每个,回答
其中作为的子串,出现的次数。

输入描述

第一行,一个整数。描述除了艾洛峰外,还有其它n座山峰。
接下来n行,每行三个整数,描述一条滑索的起点、终点、颜色。

输出描述

输出n行,每行一个整数。第i行表示,编号为i的山峰的颜色序列被记录的次数。

示例1

输入:

7
0 1 1
0 2 2
1 3 1
1 4 2
2 5 2
2 6 1
6 7 2

输出:

6
7
1
2
1
2
1

说明:

{arr}_1: [1]
{arr}_2: [2]
{arr}_3: [1, 1]
{arr}_4: [1, 2]
{arr}_5: [2, 2]
{arr}_6: [2, 1]
{arr}_7: [2, 1, 2]

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 158ms, 内存消耗: 49264K, 提交时间: 2023-07-29 22:48:10

#include <bits/stdc++.h>
using i64=long long;
int n, m;
const int N = 1e5 + 10;
typedef std::pair<int, int> PII;
std::map<int, int> tr[N];
int h[N], ne[N << 1], e[N << 1], w[N << 1], idx, sz[N];
inline void add(int a, int b, int c) {
	ne[idx] = h[a], e[idx] = b, w[idx] = c, h[a] = idx ++;
}
inline void add(int a, int b) {
	ne[idx] = h[a], e[idx] = b, h[a] = idx ++;
}
int val[N << 5], root[N << 5], tot, l[N << 5], r[N << 5], nxt[N << 5];
int dfn[N], timedelta, id[N];

inline void insert(int &u, int L, int R, int x, int v) {
	int last = u;
	u = ++ tot;
	if (L == R) {
		val[u] = v;
		return ;	
	}
	l[u] = l[last];
	r[u] = r[last];
	int mid = L + R >> 1;
	if (x <= mid) insert(l[u], L, mid, x, v);
	else insert(r[u], mid + 1, R, x, v);
}
inline int query(int u, int L, int R, int x) {
	if (L == R) return val[u];
	
	int mid = L + R >> 1;
	if (x <= mid)	return query(l[u], L, mid, x);
	return query(r[u], mid + 1, R, x);
}
inline void solve() {
	std::cin >> n;	
	memset(h, -1, sizeof h);
	for (int i = 0; i < n; i ++) {
		int a, b, c;
		std::cin >> a >> b >> c;
		add(a, b, c);
		add(b, a, c);
	}
	{
		std::function<void(int, int)> dfs = [&](int u, int fa) -> void{
			sz[u] = 1;
			for (int i = h[u]; ~i; i = ne[i]) {
				int j = e[i], v = w[i];
				if (j == fa)	continue;
				tr[u][j] = v;
				dfs(j, u);
				sz[u] += sz[j];
			}
		};
		dfs(0, -1);
	}
	
	{
		int p = 0;
		std::queue<int> q;
		for (auto &[x, v]: tr[p]) {
			q.push(x);
			nxt[v] = 0;
			insert(root[p], 1, 1e5, v, x);
		}			
		while (!q.empty()) {
			int tq = q.front();
			q.pop();
			root[tq] = root[nxt[tq]];
			for(auto &[x, v]: tr[tq]){
				int t = query(root[tq], 1, 1e5, v);
				nxt[x] = t;
				insert(root[tq], 1, 1e5, v, x);	
				q.push(x);
			}
		}
	}
	memset(h, -1, sizeof h);
	idx = 0;
	
	{
		std::vector<long long> dp(n + 1);
		for (int i = 1; i <= n; i ++) {
			dp[nxt[i]] += sz[i];
			add(nxt[i], i);
		}
		
		std::function<void(int)> dfs = [&](int u) -> void{
			for (int i = h[u]; ~i; i = ne[i]) {
				int j = e[i];
				dfs(j);
				dp[u] += dp[j];
			}
		};
		dfs(0);
		
		for (int i = 1; i <= n; i ++) dp[i] += sz[i];
		for (int i = 1; i <= n; i ++)	std::cout << dp[i] << '\n';
	}
}
int main(void) {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);
	int _ = 1;
	while (_ --) solve();
	return 0;
}

C++ 解法, 执行用时: 496ms, 内存消耗: 284812K, 提交时间: 2021-06-08 19:09:00

#include<bits/stdc++.h>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
typedef long long ll;
const int N=1e5+10;

ll ans[N];
int fail[N],q[N],t;
vector<pair<int, int>>g[N];
rope<int>go[N];
int main() {
    int n;cin>>n;
    for(int i=0; i<n; i++) {
        int u,v,c; scanf("%d%d%d",&u,&v,&c);
        g[u].emplace_back(v, c);
    }
    go[0]=rope<int>(N, 0);
    q[t++]=0;
    for(int h=0;h<t; h++) {
        int u=q[h];
        go[u]=go[fail[u]];
        for(auto [v,c]:g[u]){
            fail[v]=go[u][c];
            go[u].replace(c,v);
            q[t++]=v;
        }
    }
    for(int i=t-1;i;i--) {
        int u=q[i];
        ans[u]=1;
        for(auto [v,c]:g[u]) {
            ans[u]+=ans[v];
        }
    }
    for(int i=t-1;i;i--){
        int u=q[i];
        ans[fail[u]]+=ans[u];
    }
    for(int i=1;i<=n;i++)printf("%lld\n",ans[i]);
    return 0;
}

上一题