卡常竟能战胜最正解?
  • 板块P2105 K皇后
  • 楼主jerryxu
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/7/23 21:31
  • 上次更新2023/11/4 13:31:31
查看原帖
卡常竟能战胜最正解?
72029
jerryxu楼主2021/7/23 21:31

正解复杂度nk=1E7 卡常复杂度nm/64=6.25E6

#pragma GCC target("sse4.2")
#include <cstdio>
#include <iostream>
#include <bitset>

const int maxn=20100;

bool l[maxn],r[maxn],row[maxn];
unsigned long long f1[2][maxn/64],f2[2][maxn/64],col[maxn/64];

void write1(int k,int x){
    f1[k][(x>>6)+1]|=1ULL<<63>>(x&((1<<6)-1));
}

void write2(int k,int x){
    f2[k][(x>>6)+1]|=1ULL<<63>>(x&((1<<6)-1));
}

void writec(int x){
    col[(x>>6)+1]|=1ULL<<63>>(x&((1<<6)-1));
}

int main(){
    int n,m,k,t1,t2;
    register int ans=0;
    unsigned long long tmask;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0;i<k;i++){
        scanf("%d%d",&t1,&t2);
        row[t1]=true;
        writec(t2-1);
        if (t2<t1) l[t1-t2+1]=true;
        else write2(1,t2-t1);
        if ((m-t2+1)<t1) r[t1-(m-t2)]=true;
        else write1(1,t2+t1-2);
    }
    k=m>>6;
    tmask=0xffffffffffffffff>>(64-(m%64))<<(64-(m%64));
    for(int i=1;i<=n;i++){
        t1=i&1;
        t2=(i+1)&1;
        if (l[i]) write2(t1,0);
        if (r[i]) write1(t1,m-1);
        if (!row[i]){
            for(register int j=1;j<=k;j++)ans+=__builtin_popcountll(~(col[j] | f1[t1][j] | f2[t1][j]));
            ans+=__builtin_popcountll((~(col[k+1] | f1[t1][k+1] | f2[t1][k+1]))&tmask);
        }
        f2[t2][1]=0;
        for(register int j=1;j<=k+1;j++){
            f2[t2][j]|=f2[t1][j]>>1;f2[t2][j+1]=f2[t1][j]<<63;
            f1[t2][j-1]|=f1[t1][j]>>63;f1[t2][j]=f1[t1][j]<<1;
        }
    }
    printf("%d\n",ans);
    return 0;
}
2021/7/23 21:31
加载中...