牛客小白月赛45
比赛链接
牛客小白月赛45
F.交换
题目描述
小沙是一个机器人,虽然小沙有很多设计不完善的地方,但是小沙立志要成为一个聪明的机器人。
小沙经常遇见这样的一个问题,管理员大大要小沙将上传的指定数列进行排序。
小沙的程序指令集中每个指令会交换两个位置上的数字,哪怕那两个位置上没有数也会进行交换。
完成任务后会直接返回与给定数列长度相同的数列。
小沙的设计缺陷就在于对于每次管理员大大给定的任务,他并不能随心所欲的挑选指令集中的指令来进行交换,但他可以选择指令操作集中的一段子串从前往后按顺序执行指令来完成任务。
现在管理员大大又给了小沙许多任务,希望你可以帮小沙完成管理员大大给的任务,对于每个任务,输出最短可完成任务指令数长度。
如果小沙无法完成任务,那么他只好输出-1了QAQ。
输入描述:
第一行输入两个数字 \(1\leq n \leq 2*10^3,1\leq m \leq 10^4\)
分别代表小沙的指令集长度,以及管理员大大下发的任务数
随后\(n\)行 每行两个数字\(x,y\),代表交换\(x,y\)位置的数字 \(1\leq x,y\leq 10\)
随后\(m\)行 每行第一个数\(k\)代表这段数列有kk个数,保证给定 数是一段\(\left[ 1,k \right]\)排列。 \(1\leq k \leq10\)
输出描述:
对于每个任务输出一行整数代表答案
如果没法完成任务输出\(-1\)
输入
3 3
1 3
1 2
2 3
3 3 2 1
3 2 1 3
3 3 1 2
输出
1
1
2
解题思路
字典树
不妨反过来考虑区间 \([1,2,\dots,10]\) 经过操作子串变化后得到的序列的最少字串长度,可以将所有询问的序列加入字典树中,记录询问的编号对应的节点,然后再从操作区间中选取一个字串对区间 \([1,2,\dots,10]\) 进行操作,每到一个节点就更新答案
- 时间复杂度:\(O(10\times (n^2+m))\)
代码
// Problem: 交换
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/11222/F
// Memory Limit: 1048576 MB
// Time Limit: 4000 ms
//
// Powered by CP Editor (https://cpeditor.org)
// %%%Skyqwq
#include
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long LL;
typedef pair PII;
typedef pair PLL;
template bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
const int N=2005,M=10005,inf=0x3f3f3f3f;
int n,m,k,res[100005],q[11],idx,pid[M],trie[11][100005];
PII a[N];
void insert(int id)
{
int p=0;
for(int i=1;i<=k;i++)
{
if(!trie[q[i]][p])trie[q[i]][p]=++idx,res[idx]=inf;
p=trie[q[i]][p];
}
pid[id]=p;
}
void ask(vector &t,int len)
{
int p=0;
for(int i=1;i<=10;i++)
{
if(trie[t[i]][p])p=trie[t[i]][p],res[p]=min(res[p],len);
else
break;
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i].fi>>a[i].se;
for(int i=1;i<=m;i++)
{
cin>>k;
for(int i=1;i<=k;i++)cin>>q[i];
insert(i);
}
for(int r=1;r<=n;r++)
{
vector t(11);
for(int i=1;i<=10;i++)t[i]=i;
ask(t,0);
for(int l=r;l;l--)
{
swap(t[a[l].fi],t[a[l].se]);
ask(t,r-l+1);
}
}
for(int i=1;i<=m;i++)
cout<<(res[pid[i]]==inf?-1:res[pid[i]])<<'\n';
return 0;
}