QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#1476#867726#9682. nim 游戏JohnAlfnovthomaswmySuccess!2025-01-26 18:56:552025-01-26 18:57:01

Details

Extra Test:

Time Limit Exceeded

input:

9 20000
5 1
290320068132385891 819316158291999388 806707996649909634 508206073858256833 696890216047283941
5 1
967260073357096260 1080611516924285625 423322742425293546 829525985365769043 120818727231358585
5 1
550965563655122829 230185600245023665 782378293413070531 307141616183743196 3072845879360...

output:

221357737230254045
1
4
1 2 4 5 
69967902057253789 45374970163135846 68254678445166655 37760186564697755 
170305764282731989
1
4
2 3 4 5 
252393644633415 153138009878129942 8143545325143213 8771815434825419 
47826592986311447
1
4
1 3 4 5 
25495188648300659 10255241004136765 3606758104821028 846940522...

result:


IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#867726#9682. nim 游戏thomaswmy97 521ms132756kbC++206.9kb2025-01-23 22:17:102025-01-26 18:58:07

answer

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int M=2e4+10;
const int P=133331;
typedef long long ll;
const ll Mod=1e18+3;
const ll inf=4e18;

int T;
int n,m;
ll A[N];
ll a[N],b[N];
vector<pair<ll,int> > aa[61];
// bool vis[N];
ll mnc;

struct Node{
    vector<pair<int,ll> >  arr;

    void clear() {
        arr.clear();
    }

    void ins(int x,ll y) {
        arr.push_back({x,y});
    }

    void upd() {
        sort(arr.begin(),arr.end());
        static ll add[N];
        for(auto i:arr) add[i.first]=0;
        for(auto i:arr) add[i.first]+=i.second;
        vector<pair<int,ll> > res;
        for(auto i:arr) {
            if(!add[i.first]) continue;
            res.push_back({i.first,add[i.first]});
            add[i.first]=0;
        }
        swap(arr,res);
    }

    ll geth() {
        ll res=0;
        for(auto i:arr) res=((__int128)res*P+i.first)%Mod;
        for(auto i:arr) res=((__int128)res*P+(__int128)i.first*i.second)%Mod;
        return res;
    }

    void print() {
        printf("%d\n",arr.size());
        for(auto i:arr) printf("%d ",i.first);printf("\n");
        for(auto i:arr) printf("%lld ",i.second);printf("\n");
    }

    bool chk(ll xr) {
        ll sum=0;
        for(auto i:arr) xr^=A[i.first],xr^=A[i.first]+i.second,sum+=i.second;
        return !xr && sum==mnc;
    }
};

vector<Node> ans;
set<ll> st;
vector<int> valid;

void init() {
    ans.clear(),st.clear(),valid.clear();
    // for(int i=1;i<=n;i++) vis[i]=0;
    for(ll i=0;i<=60;i++) {
        aa[i].clear();
        for(int j=1;j<=n;j++) {
            if(a[j]>>i&1ll) continue;
            ll val=a[j]&((1ll<<i)-1);
            aa[i].push_back({val,j});
        }
        sort(aa[i].begin(),aa[i].end());
        reverse(aa[i].begin(),aa[i].end());
    }
}

ll calc(ll *a,ll now,ll xr,vector<int> arr) {
    if(now<0) return 0;
    if(!(xr>>now&1ll)) return calc(a,now-1,xr,arr);
    ll ans=0;
    pair<ll,int> mx={-1,0};
    // for(int i:arr) vis[i]=1;
    for(auto j:aa[now]) {
        if(j.first!=(a[j.second]&((1ll<<now)-1))) continue;
        mx=j;
        break;
    }
    // for(int i:arr) vis[i]=0;
    for(int i:arr) {
        if(a[i]>>now&1ll) continue;
        ll val=a[i]&((1ll<<now)-1);
        mx=max(mx,{val,i});
    }
    if(!mx.second) {
        if(a==b) {
            return inf;
        }
        for(int j=1;j<=n;j++) b[j]=a[j];
        ll mn=inf;
        for(int j=1;j<=n;j++) {
            ll cnt=(1ll<<now+1)-(a[j]&((1ll<<now+1)-1));
            xr^=b[j];
            b[j]+=cnt;
            xr^=b[j];
            arr.push_back(j);
            ll res=calc(b,60,xr,arr)+cnt;
            if(res<mn) {
                mn=res;
                valid.clear();
            }
            if(mn==res) valid.push_back(j);
            arr.pop_back();
            xr^=b[j];
            b[j]-=cnt;
            xr^=b[j];
        }
        return mn;
    }
    ll cnt=(1ll<<now)-mx.first;
    arr.push_back({mx.second});
    xr^=a[mx.second];
    ans+=cnt,a[mx.second]+=cnt;
    xr^=a[mx.second];
    ans+=calc(a,now-1,xr,arr);
    a[mx.second]-=cnt;
    return ans;
}

void solve(ll *a,ll now,ll xr,vector<int> arr,Node nd,ll sum) {
    // printf("%lld %lld:%lld\n",now,xr,sum);
    // for(int i=1;i<=n;i++) printf("%lld ",a[i]);printf("\n");
    // for(int i:arr) printf("%d ",i);printf("\n");
    sort(arr.begin(),arr.end()),arr.erase(unique(arr.begin(),arr.end()),arr.end());
    if(ans.size()>=m) return ;
    if(now<0) {
        nd.upd();
        ll h=nd.geth();
        if(st.find(h)!=st.end()) return ;
        st.insert(h);
        ans.push_back(nd);
        // if(!nd.chk(1)) printf("??????????????\n");
        return ;
    }
    if(!(xr>>now&1ll)) return solve(a,now-1,xr,arr,nd,sum);
    pair<ll,int> mx={-1,0};
    // for(int i:arr) vis[i]=1;
    for(auto j:aa[now]) {
        if(j.first!=(a[j.second]&((1ll<<now)-1))) continue;
        mx=j;
        break;
    }
    // for(int i:arr) vis[i]=0;
    for(int i:arr) {
        if(a[i]>>now&1ll) continue;
        ll val=a[i]&((1ll<<now)-1);
        mx=max(mx,{val,i});
    }
    if(!mx.second) {
        if(a==b) return ;
        for(int j=1;j<=n;j++) b[j]=a[j];
        for(int j:valid) {
            ll cnt=(1ll<<now+1)-(a[j]&((1ll<<now+1)-1));
            xr^=b[j];
            b[j]+=cnt;
            xr^=b[j];
            arr.push_back(j);
            Node v=nd;
            v.ins(j,cnt);
            solve(b,60,xr,arr,v,sum+cnt);
            if(ans.size()>=m) return ;
            arr.pop_back();
            xr^=b[j];
            b[j]-=cnt;
            xr^=b[j];
        }
        return ;
    }
    // for(int i:arr) vis[i]=1;
    for(auto j:aa[now]) {
        if(j.first!=(a[j.second]&((1ll<<now)-1))) continue;
        ll cnt=(1ll<<now)-(a[j.second]&((1ll<<now)-1));
        bool flag=a[j.second]==mx.first;
        Node v=nd;
        arr.push_back({j.second});
        v.ins(j.second,cnt);
        xr^=a[j.second];
        a[j.second]+=cnt;
        xr^=a[j.second];
        // printf(" %lld %lld-> %d %lld %d\n",now,xr,j.second,j.first,vis[j.second]);
        flag|=calc(a,now-1,xr,arr)+sum+cnt==mnc;
        if(flag) solve(a,now-1,xr,arr,v,sum+cnt);
        if(ans.size()>=m) return ;
        arr.pop_back();
        xr^=a[j.second];
        a[j.second]-=cnt;
        xr^=a[j.second];
        if(!flag) break;
    }
    // for(int i:arr) vis[i]=0;
    vector<pair<ll,int> > arrr;
    for(int i:arr) {
        if(a[i]>>now&1ll) continue;
        ll val=a[i]&((1ll<<now)-1);
        arrr.push_back({val,i});
    }
    sort(arrr.begin(),arrr.end());
    reverse(arrr.begin(),arrr.end());
    for(auto j:arrr) {
        ll cnt=(1ll<<now)-(a[j.second]&((1ll<<now)-1));
        bool flag=a[j.second]==mx.first;
        Node v=nd;
        arr.push_back({j.second});
        v.ins(j.second,cnt);
        xr^=a[j.second];
        a[j.second]+=cnt;
        xr^=a[j.second];
        flag|=calc(a,now-1,xr,arr)+sum+cnt==mnc;
        // printf("%lld %lld-> %d %lld\n",now,xr,j.second,j.first);
        if(flag) solve(a,now-1,xr,arr,v,sum+cnt);
        if(ans.size()>=m) return ;
        arr.pop_back();
        xr^=a[j.second];
        a[j.second]-=cnt;
        xr^=a[j.second];
        if(!flag) break;
    }
    return ;
}

int main() {
    // freopen("nim.in","r",stdin);
    // freopen("nim.out","w",stdout);
    scanf("%*d%d",&T);
    while(T--) {
        scanf("%d%d",&n,&m);
        ll xr=0;
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]),A[i]=a[i],xr^=a[i];
        init();
        mnc=calc(a,60,xr,{});
        printf("%lld\n",mnc);
        Node nd;
        nd.clear();
        solve(a,60,xr,{},nd,0);
        printf("%lld\n",ans.size());
        // assert(ans.size()<=m);
        for(Node i:ans) {
            if(!i.chk(xr)) printf("???????????????\n"),assert(0);
            i.print();
        }
    }
    return 0;
}