[HNOI2008]神奇的国度

本文探讨了使用链表实现基数排序的方法,并通过一个具体题目示例展示了如何在限定时间内完成排序任务。代码中详细实现了排序算法的具体步骤,包括初始化、读取输入、构建链表等过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

万古坟..发现草稿箱里还有这么个东西。发上来。以下原文。



为什么想写一下呢?

因为CDQ坑了一下...


我刚想说CDQ居然做到了用链表O(n)排序...

还动态修改。

忽然发现不对啊。

啊!原来是这个意思...好吧...╮(╯▽╰)╭

其实这个是什么意思呢?


就是基数排序啊....TAT我真的这么弱么...


大神们的程序貌似都是n^2的? ...

好吧我会说这道题时限5s么...


code:

#include<cstdio>
#include<cstdlib>
#define ot "%d"
#define kg " "
#define kh "\n"
#ifdef WIN32
#define otl "%I64d"
#else
#define otl "%lld"
#endif
#define ll long long
#define od "%lf"
#define oc "%c"
#define max(a, b) ({int _ = (a), __ = (b); _ > __ ? _ : __;})
#define min(a, b) ({int _ = (a), __ = (b); _ < __ ? _ : __;})
#define swap(a, b) ({int _ = (a); (a) = (b); (b) = _;})
#define add(a, b) ({*(++eptr) = (edge){b, h[a]}, h[a] = eptr;})
#define maxn 20005
#define maxm 2000005

using namespace std;

struct edge
{
	int t;
	edge *nt;
}eg[maxm], *h[maxn], *eptr, *e, *d;

int n, m, a, b, i, j, q, p, tot = 0, index, ans;
int arr[maxn], col[maxn], hx[maxn], t[maxn], l[maxn], r[maxn], s[maxn];
bool v[maxn];

char rd;
inline void read(int &a)
{
	a = 0; rd = getchar(); while ('0' > rd || rd > '9') rd = getchar();
	while ('0' <= rd && rd <= '9') a *= 10, a += rd - '0', rd = getchar();
}

void init()
{
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
}
int main()
{
	init();
	read(n); read(m); eptr = eg;
	while (m--)	read(a), read(b), add(a, b), add(b, a);
	for(i = 1; i <= n; ++i) l[i] = i - 1, r[i] = i + 1; r[n] = 0, s[p = 0] = 1;
	for(i = 0; i <  n; ++i)
	{
		e = h[arr[n - i] = s[p]]; v[s[p]] = 1;
		s[p] = r[s[p]]; l[s[p]] = 0;
		for(; e; e = e -> nt)
			if (!v[q = e -> t])
			{
				if (r[q]) l[r[q]] = l[q];
				if (l[q]) r[l[q]] = r[q]; else s[t[q]] = r[q];
				r[q] = s[++t[q]]; if (r[q]) l[r[q]] = q;
				l[q] = 0; s[t[q]] = q;
			}
		++p; while (!s[p]) --p;
	}
	col[arr[n]] = 1; index = 0; ans = 0;
	for(i = n - 1; i; --i)
	{
		++index;
		for(e = h[arr[i]]; e; e = e -> nt) hx[col[e -> t]] = index;
		j = 1; while (hx[j] == index) ++j;
		col[arr[i]] = j; if (j > ans) ans = j;
	}
	printf(ot, ans);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值