样例二过不了,Trie+FHQ 求调悬关
查看原帖
样例二过不了,Trie+FHQ 求调悬关
891062
Ericzc楼主2025/6/14 16:12
#include<bits/stdc++.h>

using namespace std;

int n, m;
string s[50010];
struct PII
{
	int first;
	string second;
	bool operator >(const PII &kkk)const
	{
		return (first == kkk.first ? second < kkk.second : first > kkk.first);
	}
};

struct Treap
{
	struct node
	{
		int ls, rs;
		PII key;
		int pri;
		int siz;
	};
	vector<node> tree;
	int idx;
	Treap()
	{
		tree.push_back({0, 0, {0, ""}, 0, 0});
		idx = 0;
	}
	int add(string s)
	{
		idx ++;
		tree.push_back({0, 0, {0, s}, rand(), 1});
		return idx;
	}
	void updata(int id)
	{
		tree[id].siz = tree[tree[id].ls].siz + tree[tree[id].rs].siz + 1;
	}
	void split(int u, PII x, int &L, int &R)
	{
		if(u == 0)
		{
			L = R = 0;
			return;
		}
		if(tree[u].key > x)
		{
			L = u;
			split(tree[u].rs, x, tree[u].rs, R);
		}
		else
		{
			R = u;
			split(tree[u].ls, x, L, tree[u].ls);
		}
		updata(u);
	}
	int merge(int L, int R)
	{
		if(L == 0) return R;
		if(R == 0) return L;
		if(tree[L].pri > tree[R].pri)
		{
			tree[L].rs = merge(tree[L].rs,R);
			updata(L);
			return L;
		}
		else
		{
			tree[R].ls = merge(L,tree[R].ls);
			updata(R);
			return R;
		}
	}
	void splitpm(int u, int x, int &L, int &R)
	{
		if(u == 0)
		{
			L = R = 0;
			return;
		}
		if(tree[tree[u].ls].siz >= x)
		{
			R = u;
			splitpm(tree[u].ls, x, L, tree[u].ls);
		}
		else
		{
			L = u;
			splitpm(tree[u].rs, x - tree[tree[u].ls].siz - 1, tree[u].rs, R);
		}
		updata(u);
	}
	int findk(int u, int k)
	{
		if(tree[tree[u].ls].siz + tree[tree[u].ls].siz + 1 < k) return -1;
		if(tree[tree[u].ls].siz + 1 == k) return u;
		if(tree[tree[u].ls].siz >= k) return findk(tree[u].ls, k);
		return findk(tree[u].rs, k - tree[tree[u].ls].siz);
	}
	void out(int u)
	{
		if(u == 0) return;
		out(tree[u].ls);
		cout << tree[u].key.first << "*" << tree[u].key.second << " ";
		out(tree[u].rs);
	}
}FHQ;

struct TRIE
{
	int root[500010];
	int trie[50010][30];
	int idx, cnt;
	TRIE()
	{
		idx = 1;
		cnt = 1;
	}
	void ins(int &kkk, char c, string s)
	{
		if(trie[kkk][c - 'a' + 1])
		{
			kkk = trie[kkk][c - 'a' + 1];
			root[kkk] = FHQ.merge(root[kkk], FHQ.add(s));
		}
		else
		{
			idx ++;
			kkk = trie[kkk][c - 'a' + 1] = idx;
			
			
			root[kkk] = FHQ.add(s);
		}
	}
	void insert(string s)
	{
		int lty = 1;
		for(int i = 0;i < s.size();i ++) ins(lty, s[i], s);
	}
	void updata(PII s)
	{
		int lty = 1;
		string t = s.second;
		t[t.size() - 1] --;
		for(auto i : s.second)
		{
			lty = trie[lty][i - 'a' + 1];
			int L, R, p;
			FHQ.split(root[lty], {s.first, t}, L, R);
			FHQ.splitpm(R, 1, p, R);
			string res = FHQ.tree[p].key.second;
			root[lty] = FHQ.merge(L, R);
			FHQ.tree[p].key.first ++;
			FHQ.split(root[lty], FHQ.tree[p].key, L, R);
			root[lty] = FHQ.merge(L, FHQ.merge(p, R));
		}
	}
	string query(string s, int k)
	{
		int lty = 1;
		for(int i = 0;i < s.size();i ++)
		{
			lty = trie[lty][s[i] - 'a' + 1];
			if(lty == 0) return "114514";
		}
		int L, R, p;
		FHQ.splitpm(root[lty], k - 1, L, R);
		FHQ.splitpm(R, 1, p, R);
		string res = FHQ.tree[p].key.second;
		int cs = FHQ.tree[p].key.first;
		root[lty] = FHQ.merge(L, FHQ.merge(p, R));
		updata({cs, res});
		return res;
	}
}Trie;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	srand(time(0));
	cin >> n;
	for(int i = 1;i <= n;i ++)
	{
		cin >> s[i];
		Trie.insert(s[i]);
	}
	cin >> m;
	for(int i = 1;i <= m;i ++)
	{
		string t;
		int k;
		cin >> t >> k;
		string c = Trie.query(t, k);
		if(c == "114514") cout << "404Error\n";
		else cout << c << "\n";
	}
	return 0;
}
2025/6/14 16:12
加载中...