QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#567427#9319. Bull FarmwoshiluoWA 87ms3964kbC++176.5kb2024-09-16 11:54:032024-09-16 11:54:04

Judging History

你现在查看的是最新测评结果

  • [2024-09-16 11:54:04]
  • 评测
  • 测评结果:WA
  • 用时:87ms
  • 内存:3964kb
  • [2024-09-16 11:54:03]
  • 提交

answer

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cstdint>
#include <cinttypes>

#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <bitset>
#include <algorithm>

using i32 = int32_t;
using u32 = uint32_t;
using ci32 = const int32_t;
using cu32 = const uint32_t;

using i64 = int64_t;
using u64 = uint64_t;
using ci64 = const int64_t;
using cu64 = const uint64_t;

constexpr bool is_number( const char cur ) { return cur >= '0' && cur <= '9'; }/*{{{*/
template <class T>
T read() {
	T res = 0, k = 1;
	char x = getchar();
	for( ; !is_number(x); x = getchar() )
		if( x == '-' ) 
			k = -1;
	for( ; is_number(x); x = getchar() )
		res = res * 10 + ( x - '0' );
	return res * k;
}
template <class T>
constexpr T Min( const T &a, const T &b ) { return a < b? a: b; }
template <class T>
constexpr T Max( const T &a, const T &b ) { return a > b? a: b; }
template <class T>
void chk_Min( T &a, const T &b ) { if( a > b ) a = b; }
template <class T>
void chk_Max( T &a, const T &b ) { if( a < b ) a = b; }
template <class T>
T pow( T a, int p ) {
	T res = 1;
	while(p) {
		if( p & 1 ) 
			res = res * a;
		a = a * a;
		p >>= 1;
	}
	return res;
}/*}}}*/

const int N = 2048;
const int IN = 1e6 + 1e5;

constexpr i32 decode( const char x, const char y ) { return ( x - 48 ) * 50 + ( y - 48 ); }

struct Set {/*{{{*/
	i32 set[N];
	void init( ci32 n ) { for( int i = 0; i <= n; i ++ ) set[i] = i; }
	Set( ci32 n = 0 ) { init(n); }
	int get_fa( ci32 cur ) {
		if( set[cur] == cur ) 
			return cur;
		set[cur] = get_fa( set[cur] );
		return set[cur];
	}
	i32& operator[] ( ci32 cur ) { return set[ get_fa(cur) ]; }
} set;/*}}}*/

void dfs( ci32 cur, std::vector<i32> &to, std::vector<i32> &st, std::vector<bool> &vis ) {
	if( vis[cur] )
		return ;
	vis[cur] = true;
	st.push_back(cur);
	dfs( set[ to[cur] ], to, st, vis );
}

void trojan( ci32 cur, i32 &idx, 
		std::stack<i32> &st, std::vector<bool> &vis,
		std::vector<std::list<i32>> &e, std::vector<std::vector<i32>> &list, std::vector<i32> &dfn, std::vector<i32> &low ) {/*{{{*/
	if( dfn[cur] ) 
		return ;
	idx ++;
	st.push(cur);
	vis[cur] = true;
	dfn[cur] = low[cur] = idx;
	for( auto &to: e[cur] ) {
		if( !dfn[ set[to] ] ) {
			trojan( set[to], idx, st, vis, e, list, dfn, low );
			chk_Min( low[cur], low[ set[to] ] );
		}
		else if( vis[ set[to] ] )
			chk_Min( low[cur], dfn[ set[to] ] );
	}
	if( dfn[cur] == low[cur] ) {
		list.push_back( {} );
		while( cur != st.top() ) {
			ci32 p = st.top(); st.pop();
			vis[p] = false;
			list.back().push_back(p);
		}
		st.pop();
		vis[cur] = false;
		list.back().push_back(cur);
	}
}/*}}}*/

int main() {
#ifdef woshiluo
	freopen( "l.in", "r", stdin );
	freopen( "l.out", "w", stdout );
#endif
	i32 T = read<i32>();
	while( T -- ) {
		ci32 n = read<i32>();
		ci32 l = read<i32>();
		ci32 qc = read<i32>();
		set.init(n);
		std::vector<std::vector<i32>> t(1);
		std::vector<std::list<i32>> e( n + 1 );
		struct Query { int id, a, b, c; };
		std::vector<std::vector<Query>> queries( l + 1 );
		std::vector<i32> res( qc + 1, 0 );

		for( int i = 1; i <= l; i ++ ) {
			std::vector<i32> list(1, 0);
			static char buf[IN];
			scanf( "%s", buf );
			for( int j = 0; j < n; j ++ ) {
				list.emplace_back( decode( buf[ j << 1 ], buf[ j << 1 | 1 ] ) );
			}
			t.emplace_back(list);
		}
		for( int i = 1; i <= qc; i ++ ) {
			static char buf[16];
			scanf( "%s", buf );
			ci32 a = decode( buf[0], buf[1] );
			ci32 b = decode( buf[2], buf[3] );
			ci32 c = decode( buf[4], buf[5] );
			if( c == 0 )
				res[i] = ( a == b );
			queries[c].push_back( (Query){ i, a, b, c } );
		}

		const auto merge = [&]( ci32 x, ci32 y ) {/*{{{*/
			ci32 fx = set[x];
			ci32 fy = set[y];

			e[fx].merge(e[fy]);
			set[fy] = fx;
		};/*}}}*/

		for( int o = 1; o <= l; o ++ ) {
			std::vector<i32> in( n + 1, 0 );
			for( int i = 1; i <= n; i ++ ) {
				in[ t[o][i] ] ++;
			}
			bool flag = false;
			i32 cnt_2 = 0, cnt_0 = 0;
			for( int i = 1; i <= n; i ++ ) {
				if( in[i] == 2 ) 
					cnt_2 ++;
				if( in[i] == 0 ) 
					cnt_0 ++;
				if( in[i] > 2 )
					flag = true;
			}

			if( !flag && cnt_0 <= 1 && cnt_2 <= 1 ) {/*{{{*/
				// So u can press this button any time
				if( cnt_0 == 0 ) {
					std::vector<bool> vis( n + 1 );
					for( int i = 1; i <= n; i ++ ) {
						if( !vis[i] ) {
							std::vector<i32> st;
							dfs( i, t[o], st, vis );
							while( st.size() > 1 ) {
								merge( st.back(), st[0] );
								st.pop_back();
							}
						}
					}
				}
				else {
					// So here is a simple edge
					i32 id_2 = -1, id_0 = -1;
					for( int i = 1; i <= n; i ++ ) {
						if( in[i] == 1 && in[ t[o][i] ] == 2 )
							id_2 = i;
						if( in[i] == 0 )
							id_0 = i;
					}
					e[ set[id_2] ].push_back( set[id_0] );
				}

				{
					i32 idx = 0;
					std::vector<bool> vis( n + 1 );
					std::stack<i32> st;
					std::vector<i32> dfn( n + 1, 0 ), low( n + 1, 0 );
					std::vector<std::vector<i32>> list;
					for( int i = 1; i <= n; i ++ ) {
						if( !dfn[i] ) 
							trojan( i, idx, st, vis, e, list, dfn, low );
					}
					for( auto &p: list ) {
						while( p.size() > 1 )  {
							merge( p.back(), p[0] );
							p.pop_back();
						}
					}
				}
			}/*}}}*/

			{/*{{{*/
				for( int i = 1; i <= n; i ++ ) {
					if( set[i] != i ) 
						continue;
					std::vector<i32> list;
					for( auto &to: e[i] ) 
						if( set[to] != i )
							list.push_back( set[to] );
					std::sort( list.begin(), list.end() );
					list.erase( std::unique( list.begin(), list.end() ), list.end() );
					e[i].resize(0);
					for( auto &x: list )
						e[i].push_back(x);
				}
				std::vector<i32> rin( n + 1, 0 );
				for( int i = 1; i <= n; i ++) { 
					if( set[i] != i ) 
						continue;
					for( auto &to: e[i] ) {
						rin[to] ++;
					}
				}
				std::vector<std::bitset<N>> avi( n + 1, 0 );
				std::queue<i32> q;
				for( int i = 1; i <= n; i ++ ) {
					if( set[i] != i ) 
						continue;
					avi[i][i] = true;
					if( rin[i] == 0 ) {
						q.push(i);
					}
				}
				while( !q.empty() ) {
					ci32 cur = q.front(); q.pop();
					for( auto &to: e[cur] ) {
						rin[to] --;
						avi[to] |= avi[cur];
						if( rin[to] == 0 )
							q.push(to);
					}
				}

				for( auto &query: queries[o] ) {
					if( avi[ set[ query.b ] ][ set[ query.a ] ] ) 
						res[ query.id ] = 1;
				}
			}/*}}}*/
		}
		for( int i = 1; i <= qc; i ++ ) 
			printf( "%d", res[i] );
		printf( "\n" );
	}
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3848kb

input:

2
5 2 4
0305040201
0404040404
030300
020500
050102
020501
6 2 4
030603010601
010203060504
030202
060402
050602
060401

output:

1011
0100

result:

ok 2 lines

Test #2:

score: 0
Accepted
time: 0ms
memory: 3840kb

input:

1
3 3 6
020202
030301
030201
020102
030203
010201
010303
020303
010202

output:

010101

result:

ok single line: '010101'

Test #3:

score: -100
Wrong Answer
time: 87ms
memory: 3964kb

input:

200
10 10 5000
01060:04020305080709
0103070:060204050908
09070503080401060:02
050308010204090:0607
03010502040607080:09
03080109020504060:07
06050:09040302080107
07080305010409060:02
030809010:0204060507
0:060908070201050304
060700
090:03
09080:
070405
010703
0:0100
080601
030600
070206
0:0:09
08040...

output:

011110001101101111111111111111111101111111110111011110110110111011010111111111111111111100111111111110111111110111111111111101111111111110111111111111111111110001100111111110111111111111111011101111111111111111111111111111111111111111011011110100111110111011110111111100111111101110111111111101111110...

result:

wrong answer 1st lines differ - expected: '011110001101101111111111111111...1111111111111111101111111111111', found: '011110001101101111111111111111...1111111111111111101111111011111'