QOJ.ac

QOJ

ID提交记录ID题目HackerOwner结果提交时间测评时间
#1537#876470#9685. nim 游戏MilmonChiFANSuccess!2025-02-07 20:34:192025-02-07 20:34:20

详细

Extra Test:

Time Limit Exceeded

input:

0 2
99999 10000
938379474519567783 277792110351115748 645574613916056709 227042457960011359 18608784190520870 793302322721922995 436906924970267855 458457997867246670 774047163734826657 878850862527762066 598674238538567004 1043564795977098599 967028883257821164 191351156816263040 552360485159576638...

output:


result:


ID题目提交者结果用时内存语言文件大小提交时间测评时间
#876470#9685. nim 游戏ChiFAN97 1053ms311812kbC++147.2kb2025-01-30 21:37:512025-02-07 20:37:28

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;
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) 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) return true;
                    }
                }
            }
            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){
            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
*/