QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#567427 | #9319. Bull Farm | woshiluo | WA | 87ms | 3964kb | C++17 | 6.5kb | 2024-09-16 11:54:03 | 2024-09-16 11:54:04 |
Judging History
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'