QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#1486#867136#9682. nim 游戏JohnAlfnovw4p3rSuccess!2025-01-26 21:00:162025-01-26 21:00:16

Details

Extra Test:

Time Limit Exceeded

input:

24 2
99999 3200
1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 1073741823 107374182...

output:

1073741825
3200
2
66662 66674 
1073741824 1 
2
66662 66674 
1073741823 2 
2
66662 66674 
1073741822 3 
2
66662 66674 
1073741821 4 
2
66662 66674 
1073741820 5 
2
66662 66674 
1073741819 6 
2
66662 66674 
1073741818 7 
2
66662 66674 
1073741817 8 
2
66662 66674 
1073741816 9 
2
66662 66674 
10737418...

result:


IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#867136#9682. nim 游戏w4p3r97 646ms29852kbC++205.7kb2025-01-23 09:44:182025-01-26 21:00:50

answer

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define N 100010

const ll inf = 4e18;

int n, m, m0;
ll k;
vector<vector<pair<int, ll>>>ans;
ll a[N], b[N];
bool vst[N];
int p[61][N];
vector<pair<int, ll>>Add;
vector<int>Ids;

bool cmp(int x, int y) {return b[x] > b[y];}

bool dfs(ll Xorsum, int num, int pos, ll used)
{
    if (used > k)return 0;
    
    if (pos < 0)
    {
        vector<pair<int, ll>>New, Temp;
        Temp = Add; sort(Temp.begin(), Temp.end());
        int k = Add.size();
        for (int i = 0; i < k; i ++)
        {
            if (i == 0 || Temp[i].first != New.back().first) New.push_back(Temp[i]);
            else New.back().second += Temp[i].second;
        }
        ans.push_back(New); ++ m0;

        return 1;
    }
    int t = (Xorsum >> pos) & 1;
    int flag = 0;
    if (t == 0)
    {
        flag |= dfs(Xorsum, num, pos - 1, used);
        if (m0 == m) return 1;
        if ((!num) && (n & 1))
        {
            int fl = 1;
            for (int i = 1; i <= n; i ++) 
            {
                int x = p[pos][i];
                if (vst[x] || ((a[x] >> pos) & 1)) continue;
                for (int j = i + 1; j <= n; j ++)
                {
                    int y = p[pos][j];
                    if (vst[y] || ((a[y] >> pos) & 1)) continue;
                    vst[x] = vst[y] = 1;
                    ll wx = (a[x] & ((1LL << pos) - 1)), wy = (a[y] & ((1LL << pos) - 1));
                    Add.push_back({x, (1LL << pos) - wx}); Add.push_back({y, (1LL << pos) - wy});
                    Ids.push_back(x); Ids.push_back(y);
                    fl = dfs(Xorsum ^ wx ^ wy, num + 2, pos - 1, used + (2LL << pos) - wx - wy);
                    flag |= fl;
                    Add.pop_back(); Add.pop_back();
                    Ids.pop_back(); Ids.pop_back();
                    vst[x] = vst[y] = 0;
                    if (m0 == m) return 1;
                    if (!fl)break; 
                }
                if (!fl)break;
            }
        }
    }
    else if (t == 1)
    {
        int fl = 1;
        for (int i = 1; i <= n; i ++)
        {
            int x = p[pos][i];
            if (vst[x] || ((a[x] >> pos) & 1)) continue;
            vst[x] = 1; ll wx = (a[x] & ((1LL << pos) - 1));
            Add.push_back({x, (1LL << pos) - wx}); Ids.push_back(x);
            fl = dfs(Xorsum ^ wx ^ (1LL << pos), num + 1, pos - 1, used + (1LL << pos) - wx);
            flag |= fl;
            Add.pop_back();
            Ids.pop_back();
            vst[x] = 0;
            if (m0 == m) return 1;
            if (!fl)break;
        }
        if (fl && num) 
        {
            for (auto x : Ids)
            {
                Add.push_back({x, (1LL << pos)});
                fl = dfs(Xorsum ^ (1LL << pos), num, pos - 1, used + (1LL << pos));
                Add.pop_back(); flag |= fl;
                if (m0 == m) return 1;
                if (!fl) break;
            }
        }
    }
    return flag;
}

ll sol(ll Xorsum, int num, int pos)
{
    if (pos == -1) return 0;
    
    ll ans = 4e18;
    int t = (Xorsum >> pos) & 1;
    int flag = 0;
    if (t == 0)
    {
        ans = min(ans, sol(Xorsum, num, pos - 1));
        if (!num)
        {
            bool flag = 0;
            for (int i = 1; i <= n; i ++) 
            {
                int x = p[pos][i];
                if (vst[x] || ((a[x] >> pos) & 1)) continue;
                for (int j = i + 1; j <= n; j ++)
                {
                    int y = p[pos][j];
                    if (vst[y] || ((a[y] >> pos) & 1)) continue;
                    vst[x] = vst[y] = 1;
                    ll wx = (a[x] & ((1LL << pos) - 1)), wy = (a[y] & ((1LL << pos) - 1));
                    ans = min((2LL << pos) - wx - wy + sol(Xorsum ^ wx ^ wy, num + 2, pos - 1), ans);
                    vst[x] = vst[y] = 0;
                    flag = 1; break;
                }
                if (flag)break;
            }
        }
    }
    else if (t == 1)
    {
        bool flag = 0;
        for (int i = 1; i <= n; i ++)
        {
            int x = p[pos][i];
            if (vst[x] || ((a[x] >> pos) & 1)) continue;
            vst[x] = 1;
            ll wx = (a[x] & ((1LL << pos) - 1));
            ans = min(ans, (1LL << pos) - wx + sol(Xorsum ^ wx ^ (1LL << pos), num + 1, pos - 1));
            vst[x] = 0;
            flag = 1; break;
        }
        if (!flag && num) 
        {
            ans = min(ans, (1LL << pos) + sol(Xorsum ^ (1LL << pos), num, pos - 1));
        }
    }
    return ans;
}

void sol()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    for (int j = 60; j >= 0; j --)
    {
        for (int i = 1; i <= n; i ++)p[j][i] = i;
        for (int i = 1; i <= n; i ++)
        {
            if ((a[i] >> j) & 1)b[i] = -1;
            else b[i] = (a[i] & ((1LL << j) - 1));
        }
        sort(p[j] + 1, p[j] + n + 1, cmp);
    }

    ll Xorsum = 0;
    for (int i = 1; i <= n; i ++) Xorsum ^= a[i];

    k = sol(Xorsum, 0, 60);

    dfs(Xorsum, 0, 60, 0);

    cout << k << '\n';

    cout << m0 << '\n';
    for (int i = 1; i <= m0; i ++)
    {
        cout << ans[i - 1].size() << '\n';
        for (auto temp : ans[i - 1]) cout << temp.first << ' ';
        cout << '\n';
        for (auto temp : ans[i - 1]) cout << temp.second << ' ';
        cout << '\n';
    }

    ans.clear(); Add.clear();
    for (int i = 1; i <= n; i ++)vst[i] = 0; 
    m0 = 0;
}

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int c, T; cin >> c >> T;
    while (T --) sol();
    return 0;
}
/*
1 1
5 10
15 15 7 5 3
*/