QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#1488#873775#9685. nim 游戏JohnAlfnovthomaswmySuccess!2025-01-27 08:18:462025-01-27 08:18:47

Details

Extra Test:

Wrong Answer
time: 820ms
memory: 5836kb

input:

9 12000
5 1
426154874666415547 230775647801995601 73154100211138309 660144293254219825 179558985134191357
7 1
755685331387139703 1129381059109720323 1073298371275804303 540526169824361339 1109040820699591787 825913807294869355 72489009458587049
5 1
926770130601861797 265713360417376703 9131411431414...

output:

188808965952953547
1
4
1 2 4 5 
150305877637007941 3046775164591 1884851969243087 36615189571537928 
98453992131722707
1
6
1 2 3 4 6 7 
919406011103625 5526046987644669 7565539293114737 35934582479062149 38777321160265877 9731096200531650 
16021921473373609
1
4
1 2 4 5 
9978591891201371 112491750432...

result:

wrong answer jury has better answer

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#873775#9685. nim 游戏thomaswmy97 1140ms133352kbC++207.2kb2025-01-26 22:35:152025-01-27 08:20: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];
int cntt[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++) {
        cntt[i]=0;
        aa[i].clear();
        for(int j=1;j<=n;j++) {
            cntt[i]+=a[j]>>i&1ll;
            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++) {
            int k=now+1;
            while(k<60 && cntt[k]==n-1 && !(a[j]>>k&1)) k++;
            ll cnt=(1ll<<k)-(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) {
            int k=now+1;
            while(k<60 && cntt[k]==n-1 && !(a[j]>>k&1)) k++;
            ll cnt=(1ll<<k)-(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;
}