1 条题解

  • 0
    @ 2026-5-4 17:50:45

    神秘题目。

    mm 比较小时,存在一个简单的博弈 dp 做法,直接将 aa 数组作为参数传入,在决策树上搜索,设当前深度为 dd,就把当前的 aa 分为两组,一组被 bdb_d 整除,一组不被 bdb_d 整除,接着由 dd 的奇偶性得出当前决策的人是谁,接着向下继续递归,并选出他们的最优决策(先手要最小化,后手最大化),由于每层所有 aa 数组大小和是 O(n)O(n) 级别,至多 mm 层,总复杂度是 O(nm)O(nm)

    mm 比较大时(代码设置的阈值是 3030),无需 dp,直接输出 00

    感性的理解就是 mm 比较大时,00 对于一方是答案上界,对于另一方是答案下界,所以只能取到 00

    #include<bits/stdc++.h>
    using namespace std;
    
    #define rep(i,l,r) for(int i=(l);i<=(r);++i)
    #define per(i,l,r) for(int i=(r);i>=(l);--i)
    #define pr pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define all(x) (x).begin(),(x).end()
    #define sz(x) (int)(x).size()
    #define bg(x) (x).begin()
    #define ed(x) (x).end()
    
    #define N 202508
    #define int long long
    
    int n,m,b[N];
    vector<int>a;
    
    inline int sol(vector<int>a,int d){
        if(!sz(a)){
            return 0;
        }
    
        if(d>m){
            return accumulate(all(a),0ll);
        }
    
        vector<int>la,ra;
    
        for(int x:a){
            if(x%b[d]==0){
                la.pb(x);
            }
            else{
                ra.pb(x);
            }
        }
    
        a.clear();
    
        if(d&1){
            return min(sol(la,d+1),sol(ra,d+1));
        }
    
        return max(sol(la,d+1),sol(ra,d+1));
    }
    
    signed main(){
        // freopen(".in","r",stdin);
        // freopen(".out","w",stdout);
        ios::sync_with_stdio(0);
        cin.tie(0);cout.tie(0);
    
        cin>>n>>m;
    
        if(m>30){
            cout<<0;
            return 0;
        }
    
        rep(i,1,n){
            int x;
            cin>>x;
            a.pb(x);
        }
    
        rep(i,1,m){
            cin>>b[i];
        }
    
        cout<<sol(a,1);
    
        return 0;
    }
    
    • 1

    信息

    ID
    7097
    时间
    500ms
    内存
    2048MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者