#include<bits/stdc++.h>
using namespace std ;
const int Max = 2e5 + 2 , Nax = 2e2 + 2 ;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9')
x=x*10+ch-'0',ch=getchar();
return x*f;
}
// 输入
vector < int > A[Max] ;
int Val , Key ;
int n , k , Q ;
int Sum[Max] ;
int Len[Max] ;
int r , c ;
int T ;
// dp
int id( int i , int l ) {
return Sum[i - 1] + l ;
}
bool f[Nax][Max] ; // 第 i 轮 , 以 j 结束是否可行
bool Ans[Nax][Max] ; // 第 i 轮 , 颜色 j 结尾是否可行
int Cnt[Max] ; // 前缀和
bool g[Max] ; // 以颜色 i 结尾是否可行
void Solve( ) {
// scanf("%d%d%d" , &n , &k , &Q ) ;
n = read( ) ;
k = read( ) ;
Q = read( ) ;
for(int i = 1 ; i <= n ; i ++ ) {
// scanf("%d" , &Len[i] ) ;
Len[i] = read( ) ;
Sum[i] = Sum[i - 1] + Len[i] ;
A[i].clear( ) ;
A[i].push_back( 0 ) ;
for(int l = 1 ; l <= Len[i] ; l ++ ) {
// scanf("%d" , &Key ) ;
Key = read( ) ;
A[i].push_back( Key ) ;
}
}
memset( f , false , sizeof f ) ;
memset( Ans , false , sizeof Ans ) ;
for(int i = 1 ; i <= n ; i ++ ) {
// 此时 Cnt[i] : 1 的数量的前缀和
for(int l = 1 ; l <= Len[i] ; l ++ ) {
Cnt[l] = Cnt[l - 1] + ( A[i][l] == 1 ) ;
if( Cnt[l - 1] - Cnt[max( l - k , 0 )] ) {
Ans[1][A[i][l]] = true ;
f[1][id( i , l )] = true ;
}
}
}
for(int S = 2 ; S <= Nax - 1 ; S ++ ) {
// 第 S 轮
memset( g , false , sizeof g ) ; // 清空
// 或运算均有结合率, 先算前面的
for(int i = 1 ; i <= n ; i ++ ) {
// 第 i 个小朋友
for(int l = 1 ; l <= Len[i] ; l ++ ) {
Cnt[l] = Cnt[l - 1] + g[A[i][l]] ;
f[S][id( i , l )] = Cnt[l - 1] - Cnt[max( l - k , 0 )] ;
}
for(int l = 1 ; l <= Len[i] ; l ++ ) {
g[A[i][l]] |= f[S - 1][id( i , l )] ;
}
}
memset( g , false , sizeof g ) ; // 清空
// 再算后面的
for(int i = n ; i >= 1 ; i -- ) {
// 第 i 个小朋友
for(int l = 1 ; l <= Len[i] ; l ++ ) {
Cnt[l] = Cnt[l - 1] + g[A[i][l]] ;
f[S][id( i , l )] |= Cnt[l - 1] - Cnt[max( l - k , 0 )] ;
Ans[S][A[i][l]] |= f[S][id( i , l )] ;
}
for(int l = 1 ; l <= Len[i] ; l ++ ) {
g[A[i][l]] |= f[S - 1][id( i , l )] ;
}
}
}
while( Q -- ) {
// scanf("%d%d" , &r , &c ) ;
r = read( ) ;
c = read( ) ;
// 进行 r 轮 , 结尾为 c
printf("%d\n" , Ans[r][c] ) ;
}
}
int main( ) {
scanf("%d" , &T ) ;
while( T -- ) Solve( ) ;
return false ;
}
感觉 csp 改成多测就老是被卡常,我真的是一点卡常技巧都不会,就会个 快读,主要是看题解跟我的复杂度完全一样,是因为我多循环了一遍吗QWQ
复杂度是 O(∑li×r×T)=O(105×2×102×5)=O(108),然后主要的循环在每组测试都进行了 4 次,所以就是 4×108 次指令,这个点玩意跑了2s+,关键是还没有乘法,都是加法、位运算和逻辑运算。
怎么就是过不了啊(痛苦)