我到底该怎么做才能卡过去,求助QWQ
查看原帖
我到底该怎么做才能卡过去,求助QWQ
816310
CQ_Alice楼主2024/10/29 17:34
#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)O(\sum l_i \times r \times T )=O(10^5 \times 2\times 10^2 \times 5) = O(10^8),然后主要的循环在每组测试都进行了 44 次,所以就是 4×1084\times 10^8 次指令,这个点玩意跑了2s+,关键是还没有乘法,都是加法、位运算和逻辑运算。

怎么就是过不了啊(痛苦)

2024/10/29 17:34
加载中...