补题
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';
}
}

浙公网安备 33010602011771号