补题

22(I) A B
23(II) K
22(I) A
24(I) G
EDU123 E
湖南省赛 F 听说很多典题
25上海区域赛 D G J A

25上海区域赛

D

三进制做 把?当成2,把0和1的状态压到2里面

base存三进制下每一位的位权
id[i] = x 映射当前二进制i在三进制下表示为x
sum[i]表示表示我现在在三进制下为i的子集和 eg sum[0] = a[0] sum[1] = a[1] sum[2] = a[0] + a[1]
先处理好id的映射和不含问号的所有sum的子集和
然后从低位到高位枚举?的位置 算出所有子集和
代码如下

#include <bits/stdc++.h>
using namespace std; 
#define int long long 
signed main(){
    ios::sync_with_stdio();
    cin.tie(0);
    cout.tie(0);
    int T = 1; //cin >> T;
    while(T--){
        int n; cin >> n;
        int m = (1 << n);
        vector<int> a(m);
        for(int i = 0; i < m; i++) cin >> a[i];
        vector<int> base(n + 1);
        base[0] = 1;
        for(int i = 1; i <= n; i++) base[i] = base[i - 1] * 3;
        vector<int> id(base[n] + 5), sum(base[n] + 5);
        for(int i = 0; i < m; i++){
            int x = 0;
            for(int j = 0; j < n; j++){
                if((i >> j) & 1) x += base[j];
            }
            id[i] = x;
            sum[x] = a[i];
        }
        for(int i = 0; i < n; i++){ //?的位置
            for(int j = 0; j < base[i]; j++){//低位数字含问号三进制
                for(int k = 0; k < (1 << (n - i - 1)); k++){//高位的数字不含问号二进制所以需要乘以位权
                    int x = id[k] * base[i + 1] + j;
                    sum[x + 2 * base[i]] = sum[x] + sum[x + base[i]]; 
                }
            }
        }
        int ans = 0;
        for(int i = 0; i < base[n]; i++) ans ^= sum[i];
        cout << ans << '\n';
    }
}
posted @ 2026-09-08 11:22  Ultramans  阅读(6)  评论(0)    收藏  举报