蒟蒻只能过样例!求助
查看原帖
蒟蒻只能过样例!求助
636977
CC__DIAMOND楼主2024/7/22 20:49
#include <bits/stdc++.h>
#define BAR cout<<"*******\n";
#define fst first
#define snd second
#define eb emplace_back
#define mp make_pair
#define INFILE(x) freopen(x,"r",stdin)
#define OUTFILE(x) freopen(x,"w",stdout)
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
using namespace std;
using ll=long long;
using ul=unsigned long long;
using ui=unsigned int;
using db=double;
using pii=pair<int,int>;
using pil=pair<int,ll>;
using pll=pair<ll,ll>;

namespace Solution {
    constexpr int N = 5e4+10;
    constexpr int O = 30;
    // 非常平凡的Trie,
    struct Node {
        int cnt,next[2];
        int l,r;
    } t[N*O];
    int tot=1;
    void insert(int x,int y) {
        int p = 1;
        t[1].cnt++;
        if(!t[1].l) t[1].l=y;
        t[1].r=y;
        for(int i=O-1;i>=0;--i) {
            int c = (x>>i)&1;
            if(!t[p].next[c]) t[p].next[c] = ++tot;
            p = t[p].next[c];
            t[p].cnt++;
            if(!t[p].l) t[p].l=y;
            t[p].r=y;
        }
    }
    int a[N],s1[O][N];
    ll getsum(int t1,int t2,int h) {
        ll res = 0;
        for(int i=h;i>=0;--i) {
            res<<=1;
            ll l,r,cnt1,cnt2,cnt3,cnt4;
            l = t[t1].l,r = t[t1].r;
            cnt1 = s1[i][r]-s1[i][l-1];
            cnt2 = r-l+1-cnt1;
            l = t[t2].l,r = t[t2].r;
            cnt3 = s1[i][r]-s1[i][l-1];
            cnt4 = r-l+1-cnt3;
            ll curr=cnt1*cnt4+cnt2*cnt3;
            if(t1==t2) curr>>=1;
            res+=curr;
        }
        return res;
    }
    ll getans(ll m) {
        vector<pii> a[2]; // 存储子树内的异或可以贡献答案的节点对,滚动。
        int b = 0;
        a[b].eb(1,1);
        int mth = 0;
        ll cnt1; // 可能对答案产生贡献的异或和中,这一位是1的个数
        ll ans = 0;
        for(int i=O-1;i>=0;--i) {
            cnt1 = 0;
            for(pii &j: a[b]) {
                ll c1,c2,c3,c4,currcnt;
                c1 = t[t[j.fst].next[0]].cnt;
                c2 = t[t[j.fst].next[1]].cnt;
                c3 = t[t[j.snd].next[0]].cnt;
                c4 = t[t[j.snd].next[1]].cnt;
                currcnt = c1*c4+c2*c3;
                if(j.fst==j.snd) currcnt>>=1;
                cnt1+=currcnt;
            }
            bool f;
            if(cnt1<m) {
                m-=cnt1;
                f=false;
            } else {
                f=true;
                mth|=1<<i;
            }
            for(pii &j: a[b]) {
                int p1,p2,p3,p4;
                p1 = t[j.fst].next[0];
                p2 = t[j.fst].next[1];
                p3 = t[j.snd].next[0];
                p4 = t[j.snd].next[1];
                if(f) {
                    if(p1&&p4) a[!b].eb(p1,p4);
                    if(j.fst!=j.snd&&p2&&p3) a[!b].eb(p2,p3);
                } else {
                    if(p1&&p3) a[!b].eb(p1,p3);
                    if(p2&&p4) a[!b].eb(p2,p4);
                    if(p1&&p4) ans+=getsum(p1,p4,i)+mth;
                    if(j.fst!=j.snd&&p2&&p3) ans+=getsum(p2,p3,i)+mth;
                }
            }
            a[b].clear();
            b^=1;
        }
        ans+=mth;
        return ans;
    }
    void solve() {
        ll n,m;
        cin>>n>>m;
        for(int i=1;i<=n;++i) cin>>a[i];
        if(!m) {
            cout<<"0\n";
            return;
        }
        sort(a+1,a+n+1);
        for(int i=1;i<=n;++i) {
            insert(a[i],i);
        }
        for(int i=0;i<O;++i) {
            for(int j=1;j<=n;++j) {
                s1[i][j]=s1[i][j-1]+(a[j]>>i&1);
            }
        }
        cout<<getans(m)<<'\n';
    }
}

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int T=1;
    // cin>>T;
    while(T--) {
        Solution::solve();
    }
    return 0;
}

2024/7/22 20:49
加载中...