NC225630. 智乃酱的子集与超集
描述
输入描述
第一行输入两个正整数表示智乃酱有个物品,个问题。
接下来一行个正整数表示物品的权值。
接下来行分别表示个问题。
每行第一个整数表示该查询中集合的元素个数,后面个正整数表示该集合中第个物品的编号为(下标从开始计算)。
输出描述
输出行,每行输出两个整数,中间用空格隔开。
对于每个集合,输出的所有子集的价值之和,的所有超集的价值之和。
示例1
输入:
3 5 1 5 9 1 1 1 2 2 1 2 3 1 2 3 0
输出:
1 26 5 34 10 17 52 13 0 52
说明:
异或是一个数学运算符。它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。其运算法则为:a⊕b = (¬a ∧ b) ∨ (a ∧¬b)如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。
C++(clang++ 11.0.1) 解法, 执行用时: 494ms, 内存消耗: 18832K, 提交时间: 2022-10-04 11:21:43
#include<iostream> using namespace std; typedef long long LL; int n,m; LL a[2000010],b[2000010]; int s[25]; int main() { cin>>n>>m; for(int i=0;i<n;i++)cin>>s[i]; for(int i=0;i<1<<n;i++){ for(int j=0;j<n;j++){ if(i>>j&1)a[i]^=s[j]; } b[i]=a[i]; } for(int j=0;j<n;j++){ for(int i=0;i<1<<n;i++){ if(i>>j&1)a[i]+=a[i^(1<<j)]; else b[i]+=b[i^(1<<j)]; } } while(m--){ int k; int sum=0; cin>>k; for(int i=1;i<=k;i++){ int p; cin>>p; sum+=1<<(p-1); } cout<<a[sum]<<" "<<b[sum]<<endl; } return 0; }