QOJ.ac

QOJ

ID提交记录ID题目HackerOwner结果提交时间测评时间
#1542#876478#9685. nim 游戏MilmonChiFANFailed.2025-02-08 08:10:382025-02-08 08:10:39

详细

Extra Test:

Accepted
time: 2453ms
memory: 11884kb

input:

0 20000
9 1
1052761889652839230 228074278613257518 861274445984240478 301433149460153662 707307470500114823 430613929615467411 89930617490578454 32142313357072182 1085104792025616711
11 1
703291854805762524 693634702854563988 1138609449983994021 215535121255496663 644277070134614294 9265840166938865...

output:

5
1
3
1 5 9 
1 3 1 
7
1
3
3 4 6 
1 5 1 
5
1
3
1 5 9 
1 3 1 
7
1
3
3 4 6 
1 5 1 
5
1
3
1 5 9 
1 3 1 
7
1
3
3 4 6 
1 5 1 
5
1
3
1 5 9 
1 3 1 
7
1
3
3 4 6 
1 5 1 
5
1
3
1 5 9 
1 3 1 
7
1
3
3 4 6 
1 5 1 
5
1
3
1 5 9 
1 3 1 
7
1
3
3 4 6 
1 5 1 
5
1
3
1 5 9 
1 3 1 
7
1
3
3 4 6 
1 5 1 
5
1
3
1 5 9 
1 3 1 
...

result:

ok correct answer

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#876478#9685. nim 游戏ChiFAN100 ✓1039ms283572kbC++147.6kb2025-01-30 21:47:042025-02-12 08:58:11

answer

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e5+114;
const int inf = 5e18;
int n,m,a[maxn],A[maxn],tim[maxn];
int keep(int id,int k){
    //a[id] [0,k)
    return (a[id]&((1ll<<k)-1));
}
int b[maxn];
int sum[65];
int ans;
int head[65],tail[65];
int tot;
int nxt[maxn*65],lst[maxn*65];
int dnxt[maxn][65],dlst[maxn][65];
int id[maxn][65];
int pos[maxn*65];
bool cmp(int x,int y){
    return b[x]<b[y];
}
void init(){
    for(int i=1;i<=n;i++) tim[i]=-1;
    for(int i=0;i<61;i++){
        vector<int> vec;
        for(int j=1;j<=n;j++){
            if(!((1ll<<i)&a[j]))
                vec.push_back(j),b[j]=(1ll<<i)-keep(j,i);
        }
        for(int j=1;j<=n;j++){
            if((1ll<<i)&a[j]) sum[i]++;
        }
        sort(vec.begin(),vec.end(),cmp);
        head[i]=++tot;
        for(int j=1;j<=n;j++) id[j][i]=++tot,pos[tot]=j;
        tail[i]=++tot;
        int lste=head[i];
        for(int x:vec){
            nxt[lste]=id[x][i];
            lst[id[x][i]]=lste;
            lste=id[x][i];
        }
        nxt[lste]=tail[i];
        lst[tail[i]]=lste;
    }
}
void clear(){
    for(int i=1;i<=tot;i++){
        lst[i]=nxt[i]=pos[i]=0;
    }
    for(int i=0;i<61;i++){
        head[i]=0;
        for(int j=1;j<=n;j++) id[j][i]=0;
        tail[i]=0;
        sum[i]=0;
    }
    for(int i=1;i<=n;i++) tim[i]=0;
    tot=0;
}
void delet(int u,int k){
    if(lst[id[u][k]]==0) return ;
    dlst[u][k]=lst[id[u][k]];
    dnxt[u][k]=nxt[id[u][k]];
    nxt[dlst[u][k]]=dnxt[u][k];
    lst[dnxt[u][k]]=dlst[u][k];
}
void insback(int u,int k){
    nxt[lst[tail[k]]]=id[u][k];
    lst[id[u][k]]=lst[tail[k]];
    lst[tail[k]]=id[u][k];
    nxt[id[u][k]]=tail[k];
}
void revoke(int u,int k){
    int x=lst[id[u][k]],y=nxt[id[u][k]];
    nxt[x]=y;
    lst[y]=x;
    lst[id[u][k]]=dlst[u][k],nxt[id[u][k]]=dnxt[u][k];
    if(dlst[u][k]==0) return ;
    nxt[lst[id[u][k]]]=id[u][k];
    lst[nxt[id[u][k]]]=id[u][k];        
    dlst[u][k]=dnxt[u][k]=0;
}
vector< pair<int,int> > vec;
int Delet(int u,int k){
    int res=(1ll<<k)-keep(u,k);
    vec.push_back(make_pair(u,res));
    if(res==(1ll<<k)) return res;
    A[u]=a[u];
    tim[u]=k;
    for(int i=k-1;i>=0;i--){
        if((1ll<<i)&a[u]) a[u]-=(1ll<<i),sum[i]--;
        delet(u,i);
        insback(u,i);
    }
    return res;
}
void Revoke(int u,int k){
    vec.pop_back();
    if(k!=tim[u]) return ;
    a[u]=A[u];
    A[u]=0;
    tim[u]=-1;
    for(int i=k-1;i>=0;i--){
        if((1ll<<i)&a[u]) sum[i]++;
        revoke(u,i);
    }
    return ;
}
int solve(int k,int cst,int spec){
    if(k<0) return cst;
    if(sum[k]%2==0){
        int c0=n-sum[k];
        if(spec==k){
            if(c0<2) return inf;
            int x=pos[nxt[head[k]]];
            int y=pos[nxt[nxt[head[k]]]];
            int res=solve(k-1,cst+Delet(x,k)+Delet(y,k),spec);
            Revoke(y,k);
            Revoke(x,k);
            return res;
        }else return solve(k-1,cst,spec);
    }else{
        int c0=n-sum[k];
        if(c0==0) return inf;
        if(spec==k) return inf;
        else{
            if(k>spec) return inf;
            int x=pos[nxt[head[k]]];
            int res=solve(k-1,cst+Delet(x,k),spec);
            Revoke(x,k);
            return res;
        }
    }
    return inf;
}
vector< vector< pair<int,int> > > sol;
int now;
unordered_map<int,bool> bx;
bool dfs(int k,int cst,int spec){
    if(k<0){
        if(cst==ans){
            now++;
            sol.push_back(vec);
            return true;
        }
        return false;
    }
    if(sum[k]%2==0){
        int c0=n-sum[k];
        if(spec==k){
            if(c0<2) return false;
            int x=pos[nxt[head[k]]];
            int y=pos[nxt[nxt[head[k]]]];
            bool res=dfs(k-1,cst+Delet(x,k)+Delet(y,k),spec);
            Revoke(y,k);
            Revoke(x,k);
            if(res==false) return false;
            if(now==m) return true;
            unordered_map<int,bool> vis;
            queue< pair<int,int> > q;
            q.push(make_pair(x,y));
            vis[min(x,y)*(n+1)+max(x,y)]=1;
            while(q.size()>0){
                int u=q.front().first,v=q.front().second;
                q.pop();
                if(nxt[id[u][k]]!=tail[k]){
                    int nu=pos[nxt[id[u][k]]];
                    if(vis[min(nu,v)*(n+1)+max(nu,v)]==0&&nu!=v){
                        vis[min(nu,v)*(n+1)+max(nu,v)]=1;
                        if(dfs(k-1,cst+Delet(nu,k)+Delet(v,k),spec)==true){
                            q.push(make_pair(nu,v));
                        }
                        Revoke(v,k);
                        Revoke(nu,k);
                        if(now==m){
                            swap(vis,bx);
                            bx.clear();
                            return true;
                        }
                    }
                }
                if(nxt[id[v][k]]!=tail[k]){
                    int nv=pos[nxt[id[v][k]]];
                    if(vis[min(u,nv)*(n+1)+max(u,nv)]==0&&u!=nv){
                        vis[min(u,nv)*(n+1)+max(u,nv)]=1;
                        if(dfs(k-1,cst+Delet(u,k)+Delet(nv,k),spec)==true){
                            q.push(make_pair(u,nv));
                        }
                        Revoke(nv,k);
                        Revoke(u,k);
                        if(now==m){
                            swap(vis,bx);
                            bx.clear();                            
                            return true;
                        }
                    }
                }
            }
            swap(vis,bx);
            bx.clear();
            return true;
        }else return dfs(k-1,cst,spec);
    }else{
        int c0=n-sum[k];
        if(c0==0) return false;
        if(spec==k) return false;
        else{
            if(k>spec) return false;
            int x=pos[nxt[head[k]]];
            bool res=dfs(k-1,cst+Delet(x,k),spec);
            Revoke(x,k);
            if(res==false) return false;
            else{
                if(now==m) return true;
                int u=nxt[id[x][k]];
                while(u!=tail[k]){
                    int y=pos[u];
                    bool res=dfs(k-1,cst+Delet(y,k),spec);
                    Revoke(y,k);
                    if(res==false||now==m) break;
                    u=nxt[u];
                }
            }
            return true;
        }
    }
    return false;
}
void work(){
    ans=inf;
    now=0;
    cin>>n>>m;
    sol.clear();
    for(int i=1;i<=n;i++) cin>>a[i];
    init();
    vector<int> answer;
    answer.resize(62);
    for(int i=0;i<62;i++){
        answer[i]=solve(60,0,i),ans=min(ans,answer[i]);
    }
    cout<<ans<<"\n";
    for(int i=0;i<62;i++){
        if(answer[i]==ans&&now<m){
            dfs(60,0,i);
        }
    }
    cout<<now<<"\n";
    for(vector< pair<int,int> > now:sol){
        map<int,int> mp;
        for(pair<int,int> add:now) mp[add.first]+=add.second;
        cout<<mp.size()<<"\n";
        for(pair<int,int> chifan:mp) cout<<chifan.first<<' ';
        cout<<"\n";
        for(pair<int,int> chifan:mp) cout<<chifan.second<<' ';
        cout<<"\n";
    }
    clear();
}
signed main(){
    //freopen("nim.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int c,t;
    cin>>c>>t;
    while(t--) work();
    return 0;
}
/*
0 1
5 2000
0 6 4 7 12
*/
/*
3 5
5 2000
0 12 14 13 4
5 2000
0 14 5 5 11
5 2000
0 12 3 0 1
5 2000
0 8 5 9 11
5 2000
0 8 7 1 2
*/
/*
0 1
5 2000
0 12 3 0 1
*/