QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#465076#5523. Graph Problem With Small $n$BalintRWA 1220ms128244kbC++204.5kb2024-07-06 17:12:032024-07-06 17:12:04

Judging History

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

  • [2024-07-06 17:12:04]
  • 评测
  • 测评结果:WA
  • 用时:1220ms
  • 内存:128244kb
  • [2024-07-06 17:12:03]
  • 提交

answer

#include <stdio.h>
#pragma GCC target "avx2"
#pragma GCC optimize "Ofast"
#include <immintrin.h>

typedef __m256i m256;
typedef unsigned uint;
typedef long long ll;
typedef unsigned long long ull;
#define ms(a, x) memset(a, x, sizeof(a))
#define pb push_back
#define fs first
#define sn second
#define ALL(v) begin(v), end(v)
#define SZ(v) ((int) (v).size())
#define lbv(v, x) (lower_bound(ALL(v), x) - (v).begin())
#define ubv(v, x) (upper_bound(ALL(v), x) - (v).begin())
const int INF = 0x3f3f3f3f;
const ll LLINF = 0x3f3f3f3f3f3f3f3f;
#define FR(i, n) for(int i = 0; i < (n); i++)
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define FORR(i, a, b) for(int i = (a); i >= (b); i--)
#define dbg(x) {cerr << #x << ' ' << x << endl;}
#define dbgArr(arr, n) {cerr << #arr; FR(_i, n) cerr << ' ' << (arr)[_i]; cerr << endl;}

#define vload(ptr) _mm256_loadu_si256((m256*) (ptr))
#define vstore(ptr, v) _mm256_storeu_si256((m256*) (ptr), (v))
#define vand(a, b) _mm256_and_si256(a, b)
#define vor(a, b) _mm256_or_si256(a, b)
#define vxor(a, b) _mm256_xor_si256(a, b)
#define vblendPs(a, b, c) (m256) _mm256_blendv_ps((__m256) (a), (__m256) (b), (__m256) (c))

const int S12 = 9740686;;
const int C24_11 = 2496144;
const int C24_12 = 2704156;
const int MASK = ((1 << 24) - 1);
const int MN = 24;
int n, mask;
int adjMat[MN], iAdjMat[MN];
bool ans[MN][MN];
int dpMem[C24_11+C24_12][8], (*dpMem1)[8] = dpMem, (*dpMem2)[8] = dpMem+C24_11;
int popPtr[MN+1], popSz[MN+1];
char mp[3<<MN], popMem[3*S12];

#define atMp(i) (*(int*) (mp + (i)*3))
#define atPopMem(i) (*(int*) (popMem + (i)*3))

void solvePop(int pop, int oldDp[][8], int newDp[][8]){
    m256 zeroV = _mm256_setzero_si256();
    m256 allOne = _mm256_set1_epi32(-1);

    m256 vAdj[MN];
    FR(i, MN) vAdj[i] = _mm256_set1_epi32(adjMat[i]);

    int inv = pop > n/2 ? -1 : 0;

    FR(i1, popSz[pop]){
        int s1 = (atPopMem(popPtr[pop]+i1) ^ inv) & MASK;
        m256 nsv = vxor(_mm256_set1_epi32(s1), allOne);
        m256 tmp = vand(vload(oldDp[i1]), nsv);
        vstore(oldDp[i1], zeroV);

        #define proc(n2){ \
            int s2 = s1 | (1 << n2); \
            int i2 = atMp(s2) & MASK; \
            m256 oldV = vload(newDp[i2]); \
            m256 newV = vor(oldV, vAdj[n2]); \
            m256 maskV = _mm256_slli_epi32(tmp, 31-n2); \
            vstore(newDp[i2], vblendPs(oldV, newV, maskV)); \
        }

        proc(0);
        proc(1);
        proc(2);
        proc(3);
        proc(4);
        proc(5);
        proc(6);
        proc(7);
        proc(8);
        proc(9);
        proc(10);
        proc(11);
        proc(12);
        proc(13);
        proc(14);
        proc(15);
        proc(16);
        proc(17);
        proc(18);
        proc(19);
        proc(20);
        proc(21);
        proc(22);
        proc(23);
    }
}

void solve(int *ord){
    FR(i, n) adjMat[i] = 0;
    FR(i, n) FR(j, n) adjMat[i] |= ((iAdjMat[ord[i]] >> ord[j]) & 1) << j;

    int (*oldMem)[8] = dpMem2, (*newMem)[8] = dpMem1;

    FR(n1, 8) oldMem[0][n1] = adjMat[n1];

    FR(pop, n-2){
        solvePop(pop, oldMem, newMem);
        int (*tmp)[8] = oldMem;
        oldMem = newMem, newMem = tmp;
    }

    FR(i, 8) FR(j, n) if(i != j){
        ans[ord[i]][ord[j]] = (oldMem[atMp(mask^(1<<i)^(1<<j)) & MASK][i] >> j) & 1;
    }

    m256 zeroV = _mm256_setzero_si256();
    FR(i, popSz[n-2]) vstore(oldMem+i, zeroV);
}

int choose[MN+1][MN+1];

void init(){
    FR(a, MN+1){
        choose[a][0] = 1;
        FOR(b, 1, a+1) choose[a][b] = choose[a-1][b-1] + choose[a-1][b];
    }
    FR(i, n+1) popSz[i] = choose[n][i];
    FR(i, n/2+1) popPtr[i+1] = popPtr[i] + popSz[i];
    FOR(i, n/2+1, n+1) popPtr[i] = popPtr[n-i];

    int ind[MN+1] = {};

    FR(s, 1<<n){
        int pop = __builtin_popcount(s);
        int i = ind[pop]++;
        if(pop > n/2) i = popSz[pop]-1 - i;
        else atPopMem(popPtr[pop]+i) |= s;
        atMp(s) |= i;
    }
}

int main(){
    scanf("%d\n", &n);
    FR(i, n){
        FR(j, n) iAdjMat[i] |= (getchar()-'0') << j;
        getchar();
    }

    //n = 24;
    //FR(i, n) FR(j, i) if(rng() & 1) iAdjMat[i] |= 1 << j, iAdjMat[j] |= 1 << i;

    mask = (1<<n)-1;
    init();

    int ord[MN];
    FR(i, MN) ord[i] = i;
    solve(ord);
    FR(i, n) ord[i] = (i+8) % n;
    solve(ord);
    FR(i, n) ord[i] = (i+16) % n;
    solve(ord);

    FR(i, n){
        FR(j, n) putchar('0'+ans[i][j]);
        putchar('\n');
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 7656kb

input:

4
0110
1010
1101
0010

output:

0001
0001
0000
1100

result:

ok 4 lines

Test #2:

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

input:

6
010001
101000
010100
001010
000101
100010

output:

010001
101000
010100
001010
000101
100010

result:

ok 6 lines

Test #3:

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

input:

4
0111
1011
1101
1110

output:

0111
1011
1101
1110

result:

ok 4 lines

Test #4:

score: 0
Accepted
time: 1202ms
memory: 128244kb

input:

23
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
000000000...

output:

00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
000000000000...

result:

ok 23 lines

Test #5:

score: 0
Accepted
time: 1220ms
memory: 127800kb

input:

23
00010100000000000101000
00000000010000000001000
00000000000001000000001
10000000000000000010000
00000000000000000000000
10000000000000000000000
00000001000000000000000
00000010000000000010000
00000000000001000000000
01000000000000000000000
00000000000000000000000
00000000000000000000000
000000000...

output:

00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
000000000000...

result:

ok 23 lines

Test #6:

score: -100
Wrong Answer
time: 1186ms
memory: 126960kb

input:

23
00001000000000000000000
00001000010001000000000
00000000000101000010000
00001000000100000000000
11010000010011000100000
00000000000100000000000
00000000000000000000001
00000000000000000101000
00000000000000000000000
01001000000000101010010
00000000000000000000101
00110100000010001000000
000010000...

output:

00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
00000000000000000000000
000000000000...

result:

wrong answer 17th lines differ - expected: '00000000000000000000000', found: '00000000000000000100000'