SDUTACM 山东理工大学第十六届ACM程序设计竞赛 题解

借用SDUT版《不是,哥们》镇楼

A、欢迎来到山东理工大学第十六届程序设计竞赛(我是听话的乖宝宝)

分析

分析?没有分析~

代码实现

#include <bits/stdc++.h>
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    std::cout << "YES" << "\n";
}

B、Q的网课(模拟)

分析

使用map记录每个网课的上课时间即可

代码实现

#include <bits/stdc++.h>
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n;
    std::cin >> n;
    std::map<std::string, int> mp;
    for (int i = 0; i < n; ++i) {
        std::string s;
        int x;
        std::cin >> s >> x;
        mp[s] = x;
    }
    int w, ans = 0;
    for (std::cin >> w; w--;) {
        std::string s;
        std::cin >> s;
        mp[s]--;
        if (mp[s] == 0) {
            ans += 1;
        }
    }
    std::cout << ans << '\n';
}

C、震惊!最好的走位竟然是...(bfs+dp)

分析

可以发现n最多只有100,也就是说来回至多五十步,因此只要维护以起点为中心的100*100方格内的状态,暴力维护即可。

代码实现

#include <bits/stdc++.h>
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    #define int long long
    constexpr int P = 998244353;
    int n, m, X, Y;
    std::cin >> n >> m >> X >> Y;
    std::string s;
    std::cin >> s;
    std::set<std::pair<int, int>> st;
    for (int i = 0; i < m; ++i) {
        int x, y;
        std::cin >> x >> y;
        st.emplace(x, y);
    }
    std::map<std::pair<int, int>, int> f;
    std::unordered_map<char, std::pair<int, int>> mp{
        {'U', std::pair{0, +1}}, 
        {'D', std::pair{0, -1}},
        {'L', std::pair{-1, 0}},
        {'R', std::pair{+1, 0}}
        };
    f[{X, Y}] = 1;
    for (auto dir : s) {
        auto [dx, dy] = mp[dir];
        std::map<std::pair<int, int>, int> g = f;
        for (auto [pos, cnt] : f) {
            auto [x, y] = pos;
            if (!st.count({x + dx, y + dy})) {
                x += dx, y += dy;
            }
            g[{x, y}] = (g[{x, y}] + cnt) % P;
        }
        std::swap(f, g);
    }
    std::cout << f[{X, Y}] << '\n';
}

D、会编程的老师(双指针)

分析

双指针扫一遍,时间复杂度O(nQ)

代码实现

#include <bits/stdc++.h>
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n, q;
    std::cin >> n >> q;
    std::string s;
    std::cin >> s;
    while (q--) {
        std::vector<int> c(26);
        std::string t;
        std::cin >> t;
        int ans = 0, l = 0, r = 0;
        while (r < n) {
            c[s[r] - 'A'] += 1;
            while (t.find(s[r]) != std::string::npos && c[s[r] - 'A'] > 1) {
                c[s[l] - 'A'] -= 1;
                l += 1;
            }
            bool ok = true;
            for (auto x : t) {
                ok &= c[x - 'A'] == 1;
            }
            if (ok) {
                ans = std::max(ans, r - l + 1);
            }
            r += 1;
        }
        std::cout << ans << "\n";
    }
}

E、不是,哥们(质因数分解+计算贡献)

分析

如果ai2能够被aj整除,那么ai2必然包含aj的所有质因子且对应的必须质因子数大于等于aj,则对于ai必须包含aj所有质因子且对应的的质因子数大于等于aj的数量整除二向上取整。可以发现ai106,因此直接枚举每个aj,对其进行质因数分解求出最小的使得[x2|aj]成立的x,枚举所有x的倍数进行计算,最后将aj放入桶中以便统计。

代码实现

#include <bits/stdc++.h>
std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
namespace Factorizer {
    std::vector<int> primes;
    std::vector<int> least;
    void sieve(int n) {
        std::vector<int> nums;
        least.assign(n + 1, 0);
        for (int i = 2; i <= n; ++i) {
            if (least[i] == 0) {
                least[i] = i;
                nums.push_back(i);
            }
            int now = 0;
            while (now < (int)nums.size()
                && nums[now] <= least[i] && i * nums[now] <= n) {
                least[i * nums[now]] = nums[now];
                now += 1;
            }
        }
        primes = nums;
    }
    constexpr bool miller_rabin(long long n) {
        if (n <= 1 || (n != 2 && n % 2 == 0)) return false;
        for (auto a : {3, 5, 7, 11, 13, 17, 19, 23, 29}) {
            if (n % a == 0) return n == a;
        }
        if (n < 31 * 31) return true;
        long long d = n - 1;
        while (d % 2 == 0) d /= 2;
        constexpr long long bases[] = {
            2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37
        };
        for (long long a : bases) {
            if (n == a) return true;
            long long t = d;
            long long y = 1 % n;
            for (long long _t = t; _t != 0; _t >>= 1) {
                if (_t & 1) y = (__int128) y * a % n;
                a = (__int128) a * a % n;
            }
            while (t != n - 1 && y != 1 && y != n - 1) {
                y = (__int128) y * y % n;
                t <<= 1;
            }
            if (y != n - 1 && t % 2 == 0) return false;
        }
        return true;
    }
    long long pollard_rho(long long n) {
        if (n == 1 || miller_rabin(n)) return n;
        long long now = 0;
        do {
            long long t = std::gcd(++now, n), r = t;
            if (t != 1 && t != n) return t;
            long long g = 1;
            do {
                t = ((__int128) t * t % n + now) % n;
                r = ((__int128) r * r % n + now) % n;
                r = ((__int128) r * r % n + now) % n;
            } while ((g = std::gcd(abs(t - r), n)) == 1);
            if (g != n) return g;
        } while (now < n / now);
        return 0;
    }
    std::vector<long long> factor(long long n) {
        if (n == 1) return {};
        std::vector<long long> g, d;
        d.push_back(n);
        while (!d.empty()) {
            auto v = d.back();
            d.pop_back();
            auto rho = pollard_rho(v);
            if (rho == v) {
                g.push_back(rho);
            } else {
                d.push_back(rho);
                d.push_back(v / rho);
            }
        }
        std::sort(g.begin(), g.end());
        return g;
    }
}
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    #define int long long
    int n;
    std::cin >> n;
    std::vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        std::cin >> a[i];
    }
    constexpr int N = 1e6 + 1, M = 1e3 + 1;
    std::vector<int> c(N), num(M);
    int ans = 0;
    for (int i = 0; i < n; ++i) {
        std::vector<int> fac = Factorizer::factor(a[i]);
        int x = 1;
        for (int j = 0; j < size(fac); ++j) {
            int k = j + 1;
            while (k < (int)size(fac) && fac[k] == fac[j]) {
                k += 1;
            }
            x *= std::pow<int>(fac[j], (k - j + 1) / 2);
            j = k - 1;
        }
        if (x < M) {
            ans += num[x];
        } else {
            for (int j = x; j < N; j += x) {
                ans += c[j];
            }
        }
        for (int j = 1; j < M; ++j) if (a[i] % j == 0) {
            num[j] += 1;
        }
        c[a[i]] += 1;
    }
    std::cout << ans << '\n';
}

F、森林的奥秘(并查集+树的直径)

分析

发现每次建完树每次删边计算森林直径较为麻烦,因此考虑倒着建树的同时维护每个集合的直径最大值。

代码实现

#include <bits/stdc++.h>
using Edge = int;
struct HLD {
	int n, times = 0;
	std::vector<int> siz, top, dep, fa, in, out, seq;
	std::vector<std::vector<Edge>> adj;
	HLD(const auto &adj, int root = 1) : n((int)adj.size() - 1), adj(adj) {
		siz.resize(n + 1), top.resize(n + 1), dep.resize(n + 1), in.resize(n + 1), out.resize(n + 1), seq.resize(n + 1), fa.resize(n + 1);
		dep[root] = 1, top[root] = root;
		dfs_siz(root), dfs_hld(root);
    }
	void dfs_siz(int u) {
		if (fa[u] != 0) {
			adj[u].erase(std::find(adj[u].begin(), adj[u].end(), fa[u]));
		}
		siz[u] = 1;
		for (auto &v : adj[u]) {
			fa[v] = u;
			dep[v] = dep[u] + 1;
			dfs_siz(v);
			siz[u] += siz[v];
			if (siz[v] > siz[adj[u][0]]) {
                std::swap(v, adj[u][0]);
            }
		}
	}
	void dfs_hld(int u) {
		in[u] = ++ times;
		seq[in[u]] = u;
		for (auto v : adj[u]) {
			top[v] = v == adj[u][0] ? top[u] : v;
			dfs_hld(v);
		}	
		out[u] = times;
	}
	int lca(int u, int v) {
		while (top[u] != top[v]) {
            dep[top[u]] > dep[top[v]] ? u = fa[top[u]] : v = fa[top[v]];
        }
		return dep[u] < dep[v] ? u : v;
	}
	int dist(int u, int v) { return dep[u] + dep[v] - 2 * dep[(lca(u, v))]; }
};
struct DSU {
    std::vector<int> p, siz;
    DSU(int n) : p(n), siz(n, 1) { std::iota(p.begin(), p.end(), 0); }
    int leader(int x) {
        while (x != p[x]) x = p[x] = p[p[x]];
        return x;
    }
    bool same(int x, int y) { return leader(x) == leader(y); }
    bool merge(int x, int y) {
        x = leader(x), y = leader(y);
        if (x == y) return false;
        siz[x] += siz[y], p[y] = x;
        return true;
    }
    int size(int x) { return siz[leader(x)]; }
};
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n;
    std::cin >> n;
    std::vector<std::pair<int, int>> edges(n - 1);
    std::vector<std::vector<int>> g(n + 1);
    for (auto &[a, b] : edges) {
        std::cin >> a >> b;
        g[a].emplace_back(b);
        g[b].emplace_back(a);
    }
    HLD hld(g);
    DSU dsu(n + 1);
    std::vector<int> ans(n);
    std::vector<std::array<int, 2>> f(n + 1);
    for (int i = 1; i <= n; ++i) {
        f[i] = {i, i};
    } 
    int max = 0;
    for (int i = n - 2; i >= 0; --i) {
        auto [a, b] = edges[i];
        a = dsu.leader(a), b = dsu.leader(b);
        assert(a != b);
        std::vector<int> p{f[a][0], f[a][1], f[b][0], f[b][1]};
        std::array<int, 2> res;
        int maxd = -1;
        for (int i = 0; i < 4; ++i) {
            for (int j = i + 1; j < 4; ++j) {
                int dist = hld.dist(p[i], p[j]);
                if (dist > maxd) {
                    res = {p[i], p[j]};
                    maxd = dist;
                }
            }
        }
        max = std::max(max, maxd);
        dsu.merge(a, b);
        f[dsu.leader(a)] = res;
        ans[i] = max;
    }
    for (int i = 0; i < n; ++i) {
        std::cout << ans[i] << "\n";
    }
}

G、ArmyL对比法(模拟)

分析

按题意模拟

代码实现

#include <bits/stdc++.h>
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n;
    std::cin >> n;
    std::vector<int> a(n), b(n);
    for (int i = 0; i < n; ++i) {
        std::cin >> a[i];
    }
    for (int i = 0; i < n; ++i) {
        std::cin >> b[i];
    }
    for (int i = 0; i < n; ++i) {
        if (a[i] > b[i]) {
            std::cout << "WinWinWin!!!" << '\n';
            return 0;
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) if (i != j) {
            if (a[i] > b[j]) {
                std::cout << "HaHa" << '\n';
                return 0;
            }
        }
    }
    std::cout << "AreYouOK?" << '\n';
}

H、我最喜欢吃饭了(模拟)

分析

Karashi大佬带带,按照读入顺序维护m个上升序列即可,如果有不能插入的则输出Karashi lovelove,否则输出Karashi cblcd

代码实现

#include <bits/stdc++.h>
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n, m;
    std::cin >> n >> m;
    std::vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        std::cin >> a[i], a[i]--;
    }
    std::vector<int> q(m, -1);
    for (int i = 0; i < n; ++i) {
        int u = -1;
        for (int j = 0; j < m; ++j) {
            if (q[j] < a[i] && (u == -1 || q[j] > q[u])) {
                u = j;
            }
        }
        if (u == -1) {
            std::cout << "Karashi lovelove" << '\n';
            return 0;
        }
        q[u] = a[i];
    }
    std::cout << "Karashi cblcd" << '\n';
}

I、树上跳棋(LCA+exgcd)

分析

首先选择直接跳到两个点的LCA上面,如果直接跳出了根节点那么一定无解。然后使用exgcd判断一下是否有解,随后一步一步往上跳判断即可,具体看代码实现。

代码实现1(倍增维护)

#include <bits/stdc++.h>
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n;
    std::cin >> n;
    std::vector<std::vector<int>> g(n + 1);
    for (int i = 0; i < n - 1; ++i) {
        int a, b;
        std::cin >> a >> b;
        g[a].emplace_back(b);
        g[b].emplace_back(a);
    }
    std::vector<int> d(n + 1, -1);
    const int N = std::__lg(n + 1) + 1;
    std::vector<std::vector<int>> fa(n + 1, std::vector<int>(N));
    d[1] = 1;
    auto dfs = [&](auto &&self, int u) ->void {
        for (auto v : g[u]) if (d[v] == -1) {
            d[v] = d[u] + 1;
            fa[v][0] = u;
            for (int i = 1; i < N; ++i) {
                int bs = fa[v][i - 1];
                fa[v][i] = fa[bs][i - 1];
            }
            self(self, v);
        }
    };
    dfs(dfs, 1);
    auto lca = [&](int x, int y) {
        if (d[x] < d[y]) std::swap(x, y);
        for (int i = N - 1; i >= 0; --i) if (d[fa[x][i]] >= d[y]) {
            x = fa[x][i];
        }
        if (x == y) return x;
        for (int i = N - 1; i >= 0; --i) if (fa[x][i] != fa[y][i]) {
            x = fa[x][i], y = fa[y][i];
        }
        return fa[x][0];
    };
    auto jump = [&](int x, int k) {
        int depth = d[x] - k;
        for (int i = N - 1; i >= 0; --i) if (d[fa[x][i]] >= depth) {
            x = fa[x][i];
        }
        return x;
    };
    int q;
    for (std::cin >> q; q--;) [&] {
        int p1, d1, p2, d2;
        std::cin >> p1 >> d1 >> p2 >> d2;
        int dep1 = d[p1], dep2 = d[p2];
        int root = lca(p1, p2), dep = d[root];
        int s1 = (dep1 - dep + d1 - 1) / d1 * d1, s2 = (dep2 - dep + d2 - 1) / d2 * d2;
        if (dep1 - s1 <= 0 || dep2 - s2 <= 0) {
            std::cout << "-1" << '\n';
        } else {
            if (abs(dep1 - dep2) % std::gcd(d1, d2) != 0) {
                std::cout << "-1" << '\n';
                return ;
            }
            p1 = jump(p1, s1), dep1 -= s1;
            p2 = jump(p2, s2), dep2 -= s2;
            while (dep1 > 0 && dep2 > 0) {
                if (dep1 == dep2) {
                    std::cout << p1 << "\n";
                    return ;
                }
                if (dep1 > dep2) {
                    s1 = (dep1 - dep2 + d1 - 1) / d1 * d1;
                    dep1 -= s1;
                    if (dep1 <= 0) break;
                    p1 = jump(p1, s1);
                } else {
                    s2 = (dep2 - dep1 + d2 - 1) / d2 * d2;
                    dep2 -= s2;
                    if (dep2 <= 0) break;
                    p2 = jump(p2, s2);
                    
                }
            }
            std::cout << -1 << '\n';
        }
    } ();
}

代码实现2(树剖维护)

#include <bits/stdc++.h>
using Edge = int;
struct HLD {
	int n, times = 0;
	std::vector<int> siz, top, dep, fa, in, out, seq;
	std::vector<std::vector<Edge>> adj;
	HLD(const auto &adj, int root = 1) : n((int)adj.size() - 1), adj(adj) {
		siz.resize(n + 1), top.resize(n + 1), dep.resize(n + 1), in.resize(n + 1), out.resize(n + 1), seq.resize(n + 1), fa.resize(n + 1);
		dep[root] = 1, top[root] = root;
		dfs_siz(root), dfs_hld(root);
    }
	void dfs_siz(int u) {
		if (fa[u] != 0) {
			adj[u].erase(std::find(adj[u].begin(), adj[u].end(), fa[u]));
		}
		siz[u] = 1;
		for (auto &v : adj[u]) {
			fa[v] = u;
			dep[v] = dep[u] + 1;
			dfs_siz(v);
			siz[u] += siz[v];
			if (siz[v] > siz[adj[u][0]]) {
                std::swap(v, adj[u][0]);
            }
		}
	}
	void dfs_hld(int u) {
		in[u] = ++ times;
		seq[in[u]] = u;
		for (auto v : adj[u]) {
			top[v] = v == adj[u][0] ? top[u] : v;
			dfs_hld(v);
		}	
		out[u] = times;
	}
	int lca(int u, int v) {
		while (top[u] != top[v]) {
            dep[top[u]] > dep[top[v]] ? u = fa[top[u]] : v = fa[top[v]];
        }
		return dep[u] < dep[v] ? u : v;
	}
	int rooted_lca(int a, int b, int c) { return lca(a, b) ^ lca(b, c) ^ lca(a, c); }
	int dist(int u, int v) { return dep[u] + dep[v] - 2 * dep[(lca(u, v))]; }
	bool in_subtree(int u, int v) { return in[v] <= in[u] && in[u] <= out[v]; }
	int jump(int u, int k) {
		if (dep[u] < k) return -1;
		int d = dep[u] - k;
		while (dep[top[u]] - d && u) u = fa[top[u]];
        return seq[in[u] - dep[u] + d];
	}
};
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n;
    std::cin >> n;
    std::vector<std::vector<int>> g(n + 1);
    for (int i = 1; i < n; ++i) {
        int a, b;
        std::cin >> a >> b;
        g[a].emplace_back(b);
        g[b].emplace_back(a);
    }
    HLD hld(g);
    int q;
    for (std::cin >> q; q--;) [&] {
        int p1, d1, p2, d2;
        std::cin >> p1 >> d1 >> p2 >> d2;
        int dep1 = hld.dep[p1], dep2 = hld.dep[p2];
        int lca = hld.lca(p1, p2), dep = hld.dep[lca];
        int s1 = (dep1 - dep + d1 - 1) / d1 * d1, s2 = (dep2 - dep + d2 - 1) / d2 * d2;
        if (dep1 - s1 <= 0 || dep2 - s2 <= 0) {
            std::cout << "-1" << '\n';
        } else {
            if (abs(dep1 - dep2) % std::gcd(d1, d2) != 0) {
                std::cout << "-1" << '\n';
                return ;
            }
            p1 = hld.jump(p1, s1), dep1 -= s1;
            p2 = hld.jump(p2, s2), dep2 -= s2;
            while (dep1 > 0 && dep2 > 0) {
                if (dep1 == dep2) {
                    std::cout << p1 << "\n";
                    return ;
                }
                if (dep1 > dep2) {
                    s1 = (dep1 - dep2 + d1 - 1) / d1 * d1;
                    dep1 -= s1;
                    if (dep1 <= 0) break;
                    p1 = hld.jump(p1, s1);
                } else {
                    s2 = (dep2 - dep1 + d2 - 1) / d2 * d2;
                    dep2 -= s2;
                    if (dep2 <= 0) break;
                    p2 = hld.jump(p2, s2);
                    
                }
            }
            std::cout << -1 << '\n';
        }
    } ();
}

J、这不是RMQ问题捏 : )(不知道拿什么来形容本题)

分析

本场除了K最难的题(bushi,写了两个多小时,愣是没想到答案就是每一列和的最大值QAQ。

代码实现

#include <bits/stdc++.h>
int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n, m;
    std::cin >> n >> m;
    std::vector<std::vector<int>> a(n, std::vector<int>(m));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            std::cin >> a[i][j];
        }
    }
    int ans = 0;
    for (int i = 0; i < m; ++i) {
        int sum = 0;
        for (int j = 0; j < n; ++j) {
            sum += a[j][i];
        }
        ans = std::max(ans, sum);
    }
    std::cout << ans << '\n';
}

K、猜猜数?

分析

没有分析,因为没看懂

posted @   sleeeeeping  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
  1. 1 吹梦到西洲 恋恋故人难,黄诗扶,妖扬
  2. 2 敢归云间宿 三无Marblue
敢归云间宿 - 三无Marblue
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

敢归云间宿 - 三无Marblue

词:怀袖

曲:KBShinya

编曲:向往

策划:杨颜

监制:似雨若离RainJaded/杨颜

吉他:大牛

混音:三无Marblue

和声:雾敛

母带:张锦亮

映像:似雨若离RainJaded

美术:阿尼鸭Any-a/乙配/雨谷/今风/米可/Eluan

题字:长安

酒 泼去群山眉头

酒 泼去群山眉头

月 悬在人世沧流

空杯如行舟 浪荡醉梦里走

心 生自混沌尽头

心 生自混沌尽头

对 天地自斟自酬

诗随我 遍历春秋

行流水 走笔形生意动

见珠玉 淙淙落纸成诵

拾得浮名有几声 云深处 却空空

耳畔丝竹 清商如雾

谈笑间 却是心兵穷途

飞觞醉月无归宿 便是孤独

不如就化身为风

卷狂沙 侵天幕

吹醒那 泉下望乡 的战骨

昨日边关犹灯火

眼前血海翻覆

千万人跌落青史 隔世号呼

于是沸血重剑共赴

斩以雷霆之怒

肩背相抵破阵开路

万古同歌哭

纵他春风不度 悲欢蚀骨

此去宁作吾

挣过命途 才敢写荣枯

望 云际群龙回首

望 云际群龙回首

任 飘蓬争逐身后

叹冥顽之俦 好景尽付恩仇

收 江声随酒入喉

收 江声随酒入喉

来 提笔御风同游

不觉已 换了春秋

真亦假 泼墨腾烟沉陆

有还无 蝶影纷堕幻目

我与天地周旋久

写尽梦 便成梦

夜雨浇熄 往事残烛

生死间 谁尽兴谁辜负

管他醒来归何处 心生万物

也曾对电光火雨

抛酒樽 镇天枢

护住了 人间多少 朝与暮

烧尽了阴云冥府

烧尽了阴云冥府

且看星斗尽出

浩荡荡尘埃野马 忘怀命数

于是信步鸿蒙之轻

也领苍生之重

与诗与剑颠倒与共

沉眠斜阳中

纵他世事汹涌 万类争渡

此去宁作吾

醉得糊涂 才梦得清楚

潮水 带着叹息轻抚

潮水 带着叹息轻抚

像光阴 漫过大地上幽微草木

有情世 见众生明灭往复

天生自在 何必回顾

晦暗中双掌一拊

立此身 照前路

与某个 阔别的我 决胜负

渺渺兮身外无物

无喜无悲无怖

不过是大梦一场 各自沉浮

于是纵横万相穷通

也守心底灵通

合眼识得星沉地动

也岿然不动

敢令岁月乌有 逍遥长驻

敢归云间宿

遥祝远行人 有道不孤

点击右上角即可分享
微信分享提示