接龙(chain)

题目描述

在玩惯了成语接龙之后,小 J 和他的朋友们发明了一个新的接龙规则。

总共有 nn 个人参与这个接龙游戏,第 ii 个人会获得一个整数序列 SiSi​ 作为他的词库。

一次游戏分为若干轮,每一轮规则如下:

  • nn 个人中的某个人 pp 带着他的词库 SpSp​ 进行接龙。若这不是游戏的第一轮,那么这一轮进行接龙的人不能与上一轮相同,但可以与上上轮或更往前的轮相同。
  • 接龙的人选择一个长度在 [2,k][2,k] 的 SpSp​ 的连续子序列 AA 作为这一轮的接龙序列,其中 kk 是给定的常数。若这是游戏的第一轮,那么 AA 需要以元素 11 开头,否则 AA 需要以上一轮的接龙序列的最后一个元素开头。
    • 序列 AA 是序列 SS 的连续子序列当且仅当可以通过删除 SS 的开头和结尾的若干元素(可以不删除)得到 AA。

为了强调合作,小 J 给了 nn 个参与游戏的人 qq 个任务,第 jj 个任务需要这 nn 个人进行一次游戏,在这次游戏里进行恰好 rjrj​ 轮接龙,且最后一轮的接龙序列的最后一个元素恰好为 cjcj​。为了保证任务的可行性,小 J 请来你判断这 qq 个任务是否可以完成的,即是否存在一个可能的游戏过程满足任务条件。

输入格式

本题有多组测试数据。

输入的第一行包含一个正整数 TT,表示数据组数。

接下来包含 TT 组数据,每组数据的格式如下:

第一行包含三个整数 n,k,qn,k,q,分别表示参与游戏的人数、接龙序列长度上限以及任务个数。

接下来 nn 行:

第 ii 行包含 (li+1)(li​+1) 个整数 li,Si,1,Si,2,…,Si,lili​,Si,1​,Si,2​,…,Si,li​​,其中第一个整数 lili​ 表示序列 SiSi​ 的长度,接下来 lili​ 个整数描述序列 SiSi​。

接下来 qq 行:

第 jj 行包含两个整数 rj,cjrj​,cj​,描述一个任务。

输出格式

对于每个任务:输出一行包含一个整数,若任务可以完成输出 1,否则输出 0。

输入输出样例

输入 #1

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

输出 #1

1
0
1
0
1
0
0

说明/提示

【样例 1 解释】

在下文中,我们使用 {Ai}={A1,A2,…,Ar}{Ai​}={A1​,A2​,…,Ar​} 表示一轮游戏中所有的接龙序列,{pi}={p1,p2,…,pr}{pi​}={p1​,p2​,…,pr​} 表示对应的接龙的人的编号。由于所有字符均为一位数字,为了方便我们直接使用数字字符串表示序列。

  • 对于第一组询问,p1=1p1​=1、A1=12A1​=12 是一个满足条件的游戏过程。
  • 对于第二组询问,可以证明任务不可完成。注意 p1=1p1​=1、A1=1234A1​=1234 不是合法的游戏过程,因为此时 ∣A1∣=4>k∣A1​∣=4>k。
  • 对于第三组询问,{pi}={2,1}{pi​}={2,1}、{Ai}={12,234}{Ai​}={12,234} 是一个满足条件的游戏过程。
  • 对于第四组询问,可以证明任务不可完成。注意 {pi}={2,1,1}、{Ai}={12,23,34}{pi​}={2,1,1}、{Ai​}={12,23,34} 不是一个合法的游戏过程,因为尽管所有的接龙序列长度均不超过 kk,但第二轮和第三轮由同一个人接龙,不符合要求。
  • 对于第五组询问,{pi}={1,2,3,1,2,3}{pi​}={1,2,3,1,2,3}、{Ai}={12,25,51,12,25,516}{Ai​}={12,25,51,12,25,516} 是一个满足条件的游戏过程。
  • 对于第六组询问,可以证明任务不可完成。注意每个接龙序列的长度必须大于等于 22,因此 A1=1A1​=1 不是一个合法的游戏过程。
  • 对于第七组询问,所有人的词库均不存在字符 77,因此任务显然不可完成。

【样例 2】

见选手目录下的 chain/chain2.in 与 chain/chain2.ans。

该样例满足测试点 1 的特殊性质。

【样例 3】

见选手目录下的 chain/chain3.in 与 chain/chain3.ans。

该样例满足测试点 2 的特殊性质。

【样例 4】

见选手目录下的 chain/chain4.in 与 chain/chain4.ans。

该样例满足特殊性质 A,其中前两组测试数据满足 n≤1000n≤1000、r≤10r≤10、单组测试数据内所有词库的长度和 ≤2000≤2000、q≤1000q≤1000。

【样例 5】

见选手目录下的 chain/chain5.in 与 chain/chain5.ans。

该样例满足特殊性质 B,其中前两组测试数据满足 n≤1000n≤1000、r≤10r≤10、单组测试数据内所有词库的长度和 ≤2000≤2000、q≤1000q≤1000。

【样例 6】

见选手目录下的 chain/chain6.in 与 chain/chain6.ans。

该样例满足特殊性质 C,其中前两组测试数据满足 n≤1000n≤1000、r≤10r≤10、单组测试数据内所有词库的长度和 ≤2000≤2000、q≤1000q≤1000。

【数据范围】

对于所有测试数据,保证:

  • 1≤T≤51≤T≤5;
  • 1≤n≤1051≤n≤105,2≤k≤2×1052≤k≤2×105,1≤q≤1051≤q≤105;
  • 1≤li≤2×1051≤li​≤2×105,1≤Si,j≤2×1051≤Si,j​≤2×105;
  • 1≤rj≤1021≤rj​≤102,1≤cj≤2×1051≤cj​≤2×105;
  • 设 ∑l∑l 为单组测试数据内所有 lili​ 的和,则 ∑l≤2×105∑l≤2×105。
测试点n≤n≤r≤r≤∑l≤∑l≤q≤q≤特殊性质
111031031120002000103103
2,32,31010552020102102
4,54,5103103101020002000103103A
661051051021022×1052×105105105A
7,87,8103103101020002000103103B
9,109,101051051021022×1052×105105105B
11,1211,12103103101020002000103103C
13,1413,141051051021022×1052×105105105C
15∼1715∼17103103101020002000103103
18∼2018∼201051051021022×1052×105105105

特殊性质 A:保证 k=2×105k=2×105。

特殊性质 B:保证 k≤5k≤5。

特殊性质 C:保证在单组测试数据中,任意一个字符在词库中出现次数之和均不超过 55。

代码

#include<bits/stdc++.h>
#define ls(k) k << 1
#define rs(k) k << 1 | 1
#define fi first
#define se second
#define mkp(x, y) make_pair(x, y)
#define fin(s) freopen(s, "r", stdin)
#define fout(s) freopen(s, "w", stdout)
using namespace std;
typedef long long ll;
const int N  = 2e5 + 10, M = 105;
inline ll read(){
	ll x = 0, f = 1;
	char c = getchar();
	while(c < '0' || c > '9'){
		if(c == '-')
		  f = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9'){
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return x * f;
}
inline void write(ll x){
	if(x < 0){
		putchar('-');
		x = -x;
	}
	if(x < 10){
		putchar('0' + x);
		return ;
	}
	write(x / 10);
	write(x % 10);
	return ;
}
int T, n, m, q, r, c, cnt, Max;
int len[N], h[N], f[N], s[N];
bool F[M][N];
vector<int> a[N], id[N], g[N];
vector<bool> dp[N];
void solve(){
	Max = 0;
	n = read(), m = read(), q = read();
	for(int i = 1; i <= n; ++i){
		cnt = 0;
		a[i].clear(), g[i].clear(), id[i].clear(), dp[i].clear();
		len[i] = read();
		for(int j = 0; j < len[i]; ++j){
			a[i].push_back(read());
			h[++cnt] = a[i][j];
			Max = max(Max, a[i][j]);
		}
		sort(h + 1, h + cnt + 1);
		cnt = unique(h + 1, h + cnt + 1) - (h + 1);
		for(int j = 0; j < len[i]; ++j)
		  id[i].push_back(lower_bound(h + 1, h + cnt + 1, a[i][j]) - (h + 1));
		dp[i].resize(len[i]); 
		g[i].resize(len[i]); 
	}
	for(int i = 1; i <= Max; ++i){
		s[i] = 0;
		for(int j = 1; j <= 100; ++j)
		  F[j][i] = 0;
	}
	for(int i = 1; i <= n; ++i){
		for(int j = 0; j < len[i]; ++j){
			if(j - m >= 0)
			  --f[a[i][j - m]];
			if(j && f[1]){
				F[1][a[i][j]] = dp[i][j] = 1;
				++s[a[i][j]];
				++g[i][id[i][j]];
			}
			++f[a[i][j]];
		}
		for(int j = 0; j < len[i]; ++j)
		  f[a[i][j]] = 0;
	}
	for(int k = 2; k < M; ++k){
		for(int i = 1; i <= n; ++i){
			int sum = 0;
			for(int j = 0; j < len[i]; ++j){
				dp[i][j] = 0;
				if(j - m >= 0){
					--f[a[i][j - m]];
					if(!f[a[i][j - m]]){
						if(s[a[i][j - m]] != g[i][id[i][j - m]])
						  --sum;	
					}
				}
				dp[i][j] = (sum >= 1);
				if(!f[a[i][j]]){
					if(s[a[i][j]] != g[i][id[i][j]])
					  ++sum;
				}
				++f[a[i][j]];
			}
			for(int j = 0; j < len[i]; ++j)
			  f[a[i][j]] = 0;
		}
		for(int i = 0; i < N; ++i)
		  s[i] = 0;
		for(int i = 1; i <= n; ++i){
			for(int j = 0; j < len[i]; ++j)
			  g[i][j] = 0;
			for(int j = 0; j < len[i]; ++j){
				if(dp[i][j]){
					F[k][a[i][j]] = 1;
					++s[a[i][j]];
					++g[i][id[i][j]];
				}
			}
		}
	}
	while(q--){
		r = read(), c = read();
		if(F[r][c])
		  puts("1");
		else
		  puts("0");
	}
}
int main(){
	T = read();
	while(T--)
	  solve();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值